Add domain and path checks for secure cookies eviction

This commit is contained in:
Keith Yeung 2016-12-08 02:05:38 -08:00
parent 64b456f0e2
commit 63a7e8efdf
4 changed files with 37 additions and 17 deletions

View file

@ -75,7 +75,7 @@ impl Cookie {
// Step 10 // Step 10
if cookie.httponly && source != CookieSource::HTTP { if cookie.httponly && source == CookieSource::NonHTTP {
return None; return None;
} }
@ -132,16 +132,11 @@ impl Cookie {
// http://tools.ietf.org/html/rfc6265#section-5.1.3 // http://tools.ietf.org/html/rfc6265#section-5.1.3
pub fn domain_match(string: &str, domain_string: &str) -> bool { pub fn domain_match(string: &str, domain_string: &str) -> bool {
if string == domain_string { string == domain_string ||
return true; (string.ends_with(domain_string) &&
} string.as_bytes()[string.len()-domain_string.len()-1] == b'.' &&
if string.ends_with(domain_string) && string.parse::<Ipv4Addr>().is_err() &&
string.as_bytes()[string.len()-domain_string.len()-1] == b'.' && string.parse::<Ipv6Addr>().is_err())
string.parse::<Ipv4Addr>().is_err() &&
string.parse::<Ipv6Addr>().is_err() {
return true;
}
false
} }
// http://tools.ietf.org/html/rfc6265#section-5.4 step 1 // http://tools.ietf.org/html/rfc6265#section-5.4 step 1

View file

@ -33,10 +33,31 @@ impl CookieStorage {
} }
// http://tools.ietf.org/html/rfc6265#section-5.3 // http://tools.ietf.org/html/rfc6265#section-5.3
pub fn remove(&mut self, cookie: &Cookie, source: CookieSource) -> Result<Option<Cookie>, ()> { pub fn remove(&mut self, cookie: &Cookie, url: &ServoUrl, source: CookieSource) -> Result<Option<Cookie>, ()> {
let domain = reg_host(cookie.cookie.domain.as_ref().unwrap_or(&"".to_string())); let domain = reg_host(cookie.cookie.domain.as_ref().unwrap_or(&"".to_string()));
let cookies = self.cookies_map.entry(domain).or_insert(vec![]); let cookies = self.cookies_map.entry(domain).or_insert(vec![]);
// https://www.ietf.org/id/draft-ietf-httpbis-cookie-alone-01.txt Step 2
if !cookie.cookie.secure && url.scheme() != "https" && url.scheme() != "wss" {
let new_domain = cookie.cookie.domain.as_ref().unwrap();
let new_path = cookie.cookie.path.as_ref().unwrap();
let any_overlapping = cookies.iter().any(|c| {
let existing_domain = c.cookie.domain.as_ref().unwrap();
let existing_path = c.cookie.path.as_ref().unwrap();
c.cookie.name == cookie.cookie.name &&
c.cookie.secure &&
(Cookie::domain_match(new_domain, existing_domain) ||
Cookie::domain_match(existing_domain, new_domain)) &&
Cookie::path_match(new_path, existing_path)
});
if any_overlapping {
return Err(());
}
}
// Step 11.1 // Step 11.1
let position = cookies.iter().position(|c| { let position = cookies.iter().position(|c| {
c.cookie.domain == cookie.cookie.domain && c.cookie.domain == cookie.cookie.domain &&
@ -62,8 +83,13 @@ impl CookieStorage {
} }
// http://tools.ietf.org/html/rfc6265#section-5.3 // http://tools.ietf.org/html/rfc6265#section-5.3
pub fn push(&mut self, mut cookie: Cookie, source: CookieSource) { pub fn push(&mut self, mut cookie: Cookie, url: &ServoUrl, source: CookieSource) {
let old_cookie = self.remove(&cookie, source); // https://www.ietf.org/id/draft-ietf-httpbis-cookie-alone-01.txt Step 1
if cookie.cookie.secure && url.scheme() != "https" && url.scheme() != "wss" {
return;
}
let old_cookie = self.remove(&cookie, url, source);
if old_cookie.is_err() { if old_cookie.is_err() {
// This new cookie is not allowed to overwrite an existing one. // This new cookie is not allowed to overwrite an existing one.
return; return;
@ -120,7 +146,6 @@ impl CookieStorage {
// Step 1 // Step 1
c.appropriate_for_url(url, source) c.appropriate_for_url(url, source)
}; };
// Step 2 // Step 2
let domain = reg_host(url.host_str().unwrap_or("")); let domain = reg_host(url.host_str().unwrap_or(""));
let cookies = self.cookies_map.entry(domain).or_insert(vec![]); let cookies = self.cookies_map.entry(domain).or_insert(vec![]);

View file

@ -281,7 +281,7 @@ fn set_cookie_for_url(cookie_jar: &Arc<RwLock<CookieStorage>>,
if let Ok(SetCookie(cookies)) = header { if let Ok(SetCookie(cookies)) = header {
for bare_cookie in cookies { for bare_cookie in cookies {
if let Some(cookie) = cookie::Cookie::new_wrapped(bare_cookie, request, source) { if let Some(cookie) = cookie::Cookie::new_wrapped(bare_cookie, request, source) {
cookie_jar.push(cookie, source); cookie_jar.push(cookie, request, source);
} }
} }
} }

View file

@ -312,7 +312,7 @@ impl CoreResourceManager {
resource_group: &ResourceGroup) { resource_group: &ResourceGroup) {
if let Some(cookie) = cookie::Cookie::new_wrapped(cookie, &request, source) { if let Some(cookie) = cookie::Cookie::new_wrapped(cookie, &request, source) {
let mut cookie_jar = resource_group.cookie_jar.write().unwrap(); let mut cookie_jar = resource_group.cookie_jar.write().unwrap();
cookie_jar.push(cookie, source) cookie_jar.push(cookie, request, source)
} }
} }