Filters sensitive headers when redirecting to a Location of different host than of the Referrer

Removes Cookie, Authorization and WWW-Authenticate cookies.

Resolves #10
This commit is contained in:
Steve Robinson
2017-05-11 18:27:40 +05:30
committed by Sean McArthur
parent 5a078cd1be
commit 21a28dffd1
2 changed files with 40 additions and 4 deletions

View File

@@ -16,7 +16,7 @@ use serde_json;
use serde_urlencoded; use serde_urlencoded;
use ::body::{self, Body}; use ::body::{self, Body};
use ::redirect::{self, RedirectPolicy, check_redirect}; use ::redirect::{self, RedirectPolicy, check_redirect, remove_sensitive_headers};
use ::response::Response; use ::response::Response;
static DEFAULT_USER_AGENT: &'static str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")); static DEFAULT_USER_AGENT: &'static str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));
@@ -167,7 +167,6 @@ fn new_hyper_client() -> ::Result<::hyper::Client> {
)) ))
} }
/// A builder to construct the properties of a `Request`. /// A builder to construct the properties of a `Request`.
pub struct RequestBuilder { pub struct RequestBuilder {
client: Arc<ClientRef>, client: Arc<ClientRef>,
@@ -343,6 +342,7 @@ impl RequestBuilder {
} }
urls.push(url); urls.push(url);
let action = check_redirect(&client.redirect_policy.lock().unwrap(), &loc, &urls); let action = check_redirect(&client.redirect_policy.lock().unwrap(), &loc, &urls);
match action { match action {
redirect::Action::Follow => loc, redirect::Action::Follow => loc,
redirect::Action::Stop => { redirect::Action::Stop => {
@@ -364,9 +364,8 @@ impl RequestBuilder {
} }
}; };
headers = remove_sensitive_headers(headers, &url, &urls);
debug!("redirecting to {:?} '{}'", method, url); debug!("redirecting to {:?} '{}'", method, url);
//TODO: removeSensitiveHeaders(&mut headers, &url);
} else { } else {
return Ok(::response::new(res, client.auto_ungzip.load(Ordering::Relaxed))) return Ok(::response::new(res, client.auto_ungzip.load(Ordering::Relaxed)))
} }

View File

@@ -2,6 +2,9 @@ use std::fmt;
use ::Url; use ::Url;
#[allow(unused_imports)]
use hyper::header::{Headers, Authorization, Cookie, Accept};
/// A type that controls the policy on how to handle the following of redirects. /// A type that controls the policy on how to handle the following of redirects.
/// ///
/// The default value will catch redirect loops, and has a maximum of 10 /// The default value will catch redirect loops, and has a maximum of 10
@@ -179,6 +182,16 @@ pub fn check_redirect(policy: &RedirectPolicy, next: &Url, previous: &[Url]) ->
}).inner }).inner
} }
pub fn remove_sensitive_headers(mut headers: Headers, next: &Url, previous: &[Url]) -> Headers {
let cross_host = next.host().unwrap() != previous.last().unwrap().host().unwrap();
if cross_host {
headers.remove::<Authorization<String>>();
headers.remove::<Cookie>();
headers.remove_raw("www-authenticate");
}
headers
}
/* /*
This was the desired way of doing it, but ran in to inference issues when This was the desired way of doing it, but ran in to inference issues when
using closures, since the arguments received are references (&Url and &[Url]), using closures, since the arguments received are references (&Url and &[Url]),
@@ -229,3 +242,27 @@ fn test_redirect_policy_custom() {
let next = Url::parse("http://foo/baz").unwrap(); let next = Url::parse("http://foo/baz").unwrap();
assert_eq!(check_redirect(&policy, &next, &[]), Action::Stop); assert_eq!(check_redirect(&policy, &next, &[]), Action::Stop);
} }
#[test]
fn test_remove_sensitive_headers() {
let mut headers = Headers::new();
headers.set(Accept::star());
headers.set(Authorization("let me in".to_owned()));
headers.set(
Cookie(vec![
String::from("foo=bar")
])
);
let next = Url::parse("http://initial-domain.com/path").unwrap();
let mut prev = vec![Url::parse("http://initial-domain.com/new_path").unwrap()];
assert_eq!(remove_sensitive_headers(headers.clone(), &next, &prev), headers);
prev.push(Url::parse("http://new-domain.com/path").unwrap());
let mut filtered_headers = headers.clone();
filtered_headers.remove::<Authorization<String>>();
filtered_headers.remove::<Cookie>();
assert_eq!(remove_sensitive_headers(headers.clone(), &next, &prev), filtered_headers);
}