fix(header): security fix for header values that include newlines
Newlines in header values will now be replaced with spaces when being written to strings or to sockets. This prevents headers that are built from user data to smuggle unintended headers or requests/responses. Thanks to @skylerberg for the responsible reporting of this issue, and helping to keep us all safe! BREAKING CHANGE: This technically will cause code that a calls `SetCookie.fmt_header` to panic, as it is no longer to properly write that method. Most people should not be doing this at all, and all other ways of printing headers should work just fine. The breaking change must occur in a patch version because of the security nature of the fix.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use header::{Header, Raw};
|
||||
use std::fmt::{self, Display};
|
||||
use std::fmt;
|
||||
use std::str::from_utf8;
|
||||
|
||||
|
||||
@@ -90,14 +90,26 @@ impl Header for SetCookie {
|
||||
Err(::Error::Header)
|
||||
}
|
||||
}
|
||||
fn fmt_header(&self, _f: &mut fmt::Formatter) -> fmt::Result {
|
||||
panic!("SetCookie cannot be used with fmt_header, must use fmt_multi_header");
|
||||
}
|
||||
|
||||
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for (i, cookie) in self.0.iter().enumerate() {
|
||||
if i != 0 {
|
||||
try!(f.write_str("\r\nSet-Cookie: "));
|
||||
}
|
||||
try!(Display::fmt(cookie, f));
|
||||
|
||||
fn fmt_multi_header(&self, f: &mut ::header::MultilineFormatter) -> fmt::Result {
|
||||
for cookie in &self.0 {
|
||||
try!(f.fmt_line(cookie));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_cookie_fmt() {
|
||||
use ::header::Headers;
|
||||
let mut headers = Headers::new();
|
||||
headers.set(SetCookie(vec![
|
||||
"foo=bar".into(),
|
||||
"baz=quux".into(),
|
||||
]));
|
||||
assert_eq!(headers.to_string(), "Set-Cookie: foo=bar\r\nSet-Cookie: baz=quux\r\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user