diff options
-rw-r--r-- | components/net/cookie.rs | 27 | ||||
-rw-r--r-- | tests/unit/net/cookie.rs | 66 |
2 files changed, 89 insertions, 4 deletions
diff --git a/components/net/cookie.rs b/components/net/cookie.rs index 7029ddee090..e8e7be6733d 100644 --- a/components/net/cookie.rs +++ b/components/net/cookie.rs @@ -82,7 +82,11 @@ impl Cookie { }; // Step 7 - let mut path = cookie.path().unwrap_or("").to_owned(); + let mut has_path_specified = true; + let mut path = cookie.path().unwrap_or_else(|| { + has_path_specified = false; + "" + }).to_owned(); if path.chars().next() != Some('/') { path = Cookie::default_path(&request.path().to_owned()).to_string(); } @@ -94,10 +98,25 @@ impl Cookie { return None; } + // https://tools.ietf.org/html/draft-west-cookie-prefixes-04#section-4 + // Step 1 of cookie prefixes + if (cookie.name().starts_with("__Secure-") || cookie.name().starts_with("__Host-")) && + !(cookie.secure() && request.is_secure_scheme()) + { + return None; + } + + // Step 2 of cookie prefixes + if cookie.name().starts_with("__Host-") && + !(host_only && has_path_specified && cookie.path().unwrap() == "/") + { + return None; + } + Some(Cookie { - cookie: cookie, - host_only: host_only, - persistent: persistent, + cookie, + host_only, + persistent, creation_time: now(), last_access: now(), expiry_time: expiry_time.map(Serde), diff --git a/tests/unit/net/cookie.rs b/tests/unit/net/cookie.rs index 44b80a1a21e..0508f5ae4ec 100644 --- a/tests/unit/net/cookie.rs +++ b/tests/unit/net/cookie.rs @@ -100,6 +100,72 @@ fn fn_cookie_constructor() { assert!(Cookie::new_wrapped(cookie, u, CookieSource::HTTP).is_some()); } +#[test] +fn test_cookie_secure_prefix() { + let url = &ServoUrl::parse("https://example.com").unwrap(); + let cookie = cookie_rs::Cookie::parse("__Secure-SID=12345").unwrap(); + assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none()); + + let url = &ServoUrl::parse("http://example.com").unwrap(); + let cookie = cookie_rs::Cookie::parse("__Secure-SID=12345; Secure").unwrap(); + assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none()); + + let url = &ServoUrl::parse("https://example.com").unwrap(); + let cookie = cookie_rs::Cookie::parse("__Secure-SID=12345; Secure").unwrap(); + assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_some()); + + let url = &ServoUrl::parse("https://example.com").unwrap(); + let cookie = cookie_rs::Cookie::parse("__Secure-SID=12345; Domain=example.com").unwrap(); + assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none()); + + let url = &ServoUrl::parse("http://example.com").unwrap(); + let cookie = cookie_rs::Cookie::parse("__Secure-SID=12345; Secure; Domain=example.com").unwrap(); + assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none()); + + let url = &ServoUrl::parse("https://example.com").unwrap(); + let cookie = cookie_rs::Cookie::parse("__Secure-SID=12345; Secure; Domain=example.com").unwrap(); + assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_some()); +} + +#[test] +fn test_cookie_host_prefix() { + let url = &ServoUrl::parse("https://example.com").unwrap(); + let cookie = cookie_rs::Cookie::parse("__Host-SID=12345").unwrap(); + assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none()); + + let url = &ServoUrl::parse("http://example.com").unwrap(); + let cookie = cookie_rs::Cookie::parse("__Host-SID=12345; Secure").unwrap(); + assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none()); + + let url = &ServoUrl::parse("https://example.com").unwrap(); + let cookie = cookie_rs::Cookie::parse("__Host-SID=12345; Secure").unwrap(); + assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none()); + + let url = &ServoUrl::parse("https://example.com").unwrap(); + let cookie = cookie_rs::Cookie::parse("__Host-SID=12345; Domain=example.com").unwrap(); + assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none()); + + let url = &ServoUrl::parse("https://example.com").unwrap(); + let cookie = cookie_rs::Cookie::parse("__Host-SID=12345; Domain=example.com; Path=/").unwrap(); + assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none()); + + let url = &ServoUrl::parse("http://example.com").unwrap(); + let cookie = cookie_rs::Cookie::parse("__Host-SID=12345; Secure; Domain=example.com").unwrap(); + assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none()); + + let url = &ServoUrl::parse("https://example.com").unwrap(); + let cookie = cookie_rs::Cookie::parse("__Host-SID=12345; Secure; Domain=example.com").unwrap(); + assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none()); + + let url = &ServoUrl::parse("https://example.com").unwrap(); + let cookie = cookie_rs::Cookie::parse("__Host-SID=12345; Secure; Domain=example.com; Path=/").unwrap(); + assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none()); + + let url = &ServoUrl::parse("https://example.com").unwrap(); + let cookie = cookie_rs::Cookie::parse("__Host-SID=12345; Secure; Path=/").unwrap(); + assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_some()); +} + #[cfg(target_os = "windows")] fn delay_to_ensure_different_timestamp() { use std::thread; |