Skip to content

Commit eee4625

Browse files
committed
Merge pull request #290 from hyperium/max-headers
fix(headers): add limit to maximum headers that should be parsed
2 parents c983ebf + f18a8fb commit eee4625

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

src/header/mod.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use mucell::MuCell;
2020
use uany::{UnsafeAnyExt};
2121
use unicase::UniCase;
2222

23-
use {http, HttpResult};
23+
use {http, HttpResult, HttpError};
2424

2525
pub use self::shared::{Encoding, QualityItem, qitem};
2626
pub use self::common::*;
@@ -118,6 +118,10 @@ pub struct Headers {
118118
data: HashMap<HeaderName, MuCell<Item>>
119119
}
120120

121+
// To prevent DOS from a server sending a never ending header.
122+
// The value was copied from curl.
123+
const MAX_HEADERS_LENGTH: u32 = 100 * 1024;
124+
121125
impl Headers {
122126

123127
/// Creates a new, empty headers map.
@@ -130,10 +134,16 @@ impl Headers {
130134
#[doc(hidden)]
131135
pub fn from_raw<R: Reader>(rdr: &mut R) -> HttpResult<Headers> {
132136
let mut headers = Headers::new();
137+
let mut count = 0u32;
133138
loop {
134139
match try!(http::read_header(rdr)) {
135140
Some((name, value)) => {
136141
debug!("raw header: {:?}={:?}", name, &value[]);
142+
count += (name.len() + value.len()) as u32;
143+
if count > MAX_HEADERS_LENGTH {
144+
debug!("Max header size reached, aborting");
145+
return Err(HttpError::HttpHeaderError)
146+
}
137147
let name = UniCase(Owned(name));
138148
let mut item = match headers.data.entry(name) {
139149
Entry::Vacant(entry) => entry.insert(MuCell::new(Item::raw(vec![]))),

0 commit comments

Comments
 (0)