aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/net/cookie.rs27
-rw-r--r--tests/unit/net/cookie.rs66
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;