Skip to content
This repository was archived by the owner on Feb 4, 2021. It is now read-only.

Commit 41e4f52

Browse files
alcerabbitinspace
authored andcommitted
fix: Sanitize custom metadata (hyperium#138)
1 parent a3aa9a7 commit 41e4f52

File tree

3 files changed

+60
-2
lines changed

3 files changed

+60
-2
lines changed

tonic/src/metadata/map.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,18 @@ pub struct OccupiedEntry<'a, VE: ValueEncoding> {
197197
// ===== impl MetadataMap =====
198198

199199
impl MetadataMap {
200+
// Headers reserved by the gRPC protocol.
201+
pub(crate) const GRPC_RESERVED_HEADERS: [&'static str; 8] = [
202+
"te",
203+
"user-agent",
204+
"content-type",
205+
"grpc-timeout",
206+
"grpc-message",
207+
"grpc-encoding",
208+
"grpc-message-type",
209+
"grpc-status",
210+
];
211+
200212
/// Create an empty `MetadataMap`.
201213
///
202214
/// The map will be created without any capacity. This function will not
@@ -237,6 +249,13 @@ impl MetadataMap {
237249
self.headers
238250
}
239251

252+
pub(crate) fn into_sanitized_headers(mut self) -> http::HeaderMap {
253+
for r in &Self::GRPC_RESERVED_HEADERS {
254+
self.headers.remove(*r);
255+
}
256+
self.headers
257+
}
258+
240259
/// Create an empty `MetadataMap` with the specified capacity.
241260
///
242261
/// The returned map will allocate internal storage in order to hold about

tonic/src/request.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ impl<T> Request<T> {
149149
*request.version_mut() = http::Version::HTTP_2;
150150
*request.method_mut() = http::Method::POST;
151151
*request.uri_mut() = uri;
152-
*request.headers_mut() = self.metadata.into_headers();
152+
*request.headers_mut() = self.metadata.into_sanitized_headers();
153153

154154
request
155155
}
@@ -209,3 +209,23 @@ impl<T> sealed::Sealed for T {}
209209
mod sealed {
210210
pub trait Sealed {}
211211
}
212+
213+
#[cfg(test)]
214+
mod tests {
215+
use super::*;
216+
use crate::metadata::MetadataValue;
217+
use http::Uri;
218+
219+
#[test]
220+
fn reserved_headers_are_excluded() {
221+
let mut r = Request::new(1);
222+
223+
for header in &MetadataMap::GRPC_RESERVED_HEADERS {
224+
r.metadata_mut()
225+
.insert(*header, MetadataValue::from_static("invalid"));
226+
}
227+
228+
let http_request = r.into_http(Uri::default());
229+
assert!(http_request.headers().is_empty());
230+
}
231+
}

tonic/src/response.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl<T> Response<T> {
7272
let mut res = http::Response::new(self.message);
7373

7474
*res.version_mut() = http::Version::HTTP_2;
75-
*res.headers_mut() = self.metadata.into_headers();
75+
*res.headers_mut() = self.metadata.into_sanitized_headers();
7676

7777
res
7878
}
@@ -89,3 +89,22 @@ impl<T> Response<T> {
8989
}
9090
}
9191
}
92+
93+
#[cfg(test)]
94+
mod tests {
95+
use super::*;
96+
use crate::metadata::MetadataValue;
97+
98+
#[test]
99+
fn reserved_headers_are_excluded() {
100+
let mut r = Response::new(1);
101+
102+
for header in &MetadataMap::GRPC_RESERVED_HEADERS {
103+
r.metadata_mut()
104+
.insert(*header, MetadataValue::from_static("invalid"));
105+
}
106+
107+
let http_response = r.into_http();
108+
assert!(http_response.headers().is_empty());
109+
}
110+
}

0 commit comments

Comments
 (0)