aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/constellation/constellation.rs3
-rw-r--r--components/net/fetch/methods.rs119
-rw-r--r--components/net/http_loader.rs2
-rw-r--r--components/script/dom/dedicatedworkerglobalscope.rs11
-rw-r--r--components/script/dom/document.rs27
-rw-r--r--components/script/dom/domimplementation.rs2
-rw-r--r--components/script/dom/domparser.rs2
-rw-r--r--components/script/dom/eventsource.rs1
-rw-r--r--components/script/dom/globalscope.rs15
-rw-r--r--components/script/dom/htmlformelement.rs1
-rw-r--r--components/script/dom/htmliframeelement.rs3
-rw-r--r--components/script/dom/htmlimageelement.rs1
-rw-r--r--components/script/dom/htmllinkelement.rs3
-rw-r--r--components/script/dom/htmlmediaelement.rs1
-rw-r--r--components/script/dom/htmlscriptelement.rs4
-rw-r--r--components/script/dom/location.rs1
-rw-r--r--components/script/dom/node.rs1
-rw-r--r--components/script/dom/notification.rs1
-rw-r--r--components/script/dom/request.rs1
-rw-r--r--components/script/dom/servoparser/mod.rs1
-rw-r--r--components/script/dom/servoparser/prefetch.rs5
-rw-r--r--components/script/dom/websocket.rs1
-rw-r--r--components/script/dom/windowproxy.rs7
-rw-r--r--components/script/dom/workerglobalscope.rs3
-rw-r--r--components/script/dom/xmldocument.rs4
-rw-r--r--components/script/dom/xmlhttprequest.rs2
-rw-r--r--components/script/fetch.rs4
-rw-r--r--components/script/links.rs1
-rw-r--r--components/script/navigation.rs1
-rw-r--r--components/script/script_thread.rs1
-rw-r--r--components/script/serviceworker_manager.rs2
-rw-r--r--components/script/stylesheet_loader.rs1
-rw-r--r--components/shared/net/request.rs13
-rw-r--r--components/shared/script/lib.rs6
-rw-r--r--components/url/lib.rs28
-rw-r--r--components/url/origin.rs56
36 files changed, 287 insertions, 48 deletions
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs
index 0cfe698106c..69547e3f6a0 100644
--- a/components/constellation/constellation.rs
+++ b/components/constellation/constellation.rs
@@ -1329,6 +1329,7 @@ where
ReferrerPolicy::EmptyString,
None,
None,
+ false,
);
let ctx_id = BrowsingContextId::from(webview_id);
let pipeline_id = match self.browsing_contexts.get(&ctx_id) {
@@ -3046,6 +3047,7 @@ where
ReferrerPolicy::EmptyString,
None,
None,
+ false,
);
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
let is_private = false;
@@ -4464,6 +4466,7 @@ where
ReferrerPolicy::EmptyString,
None,
None,
+ false,
);
self.load_url_for_webdriver(
webview_id,
diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs
index 8c5758830c1..49b063f1bc8 100644
--- a/components/net/fetch/methods.rs
+++ b/components/net/fetch/methods.rs
@@ -34,7 +34,7 @@ use net_traits::{
use rustls_pki_types::CertificateDer;
use serde::{Deserialize, Serialize};
use servo_arc::Arc as ServoArc;
-use servo_url::{Host, ServoUrl};
+use servo_url::{Host, ImmutableOrigin, ServoUrl};
use tokio::sync::mpsc::{UnboundedReceiver as TokioReceiver, UnboundedSender as TokioSender};
use super::fetch_params::FetchParams;
@@ -278,7 +278,6 @@ pub async fn main_fetch(
// Step 7. If should request be blocked due to a bad port, should fetching request be blocked
// as mixed content, or should request be blocked by Content Security Policy returns blocked,
// then set response to a network error.
- // TODO: check "should fetching request be blocked as mixed content"
if should_request_be_blocked_by_csp(request, &policy_container) == csp::CheckResult::Blocked {
warn!("Request blocked by CSP");
response = Some(Response::network_error(NetworkError::Internal(
@@ -290,6 +289,11 @@ pub async fn main_fetch(
"Request attempted on bad port".into(),
)));
}
+ if should_request_be_blocked_as_mixed_content(request) {
+ response = Some(Response::network_error(NetworkError::Internal(
+ "Blocked as mixed content".into(),
+ )));
+ }
// Step 8: If request’s referrer policy is the empty string, then set request’s referrer policy
// to request’s policy container’s referrer policy.
@@ -480,6 +484,8 @@ pub async fn main_fetch(
should_be_blocked_due_to_nosniff(request.destination, &response.headers);
let should_replace_with_mime_type_error = !response_is_network_error &&
should_be_blocked_due_to_mime_type(request.destination, &response.headers);
+ let should_replace_with_mixed_content = !response_is_network_error &&
+ should_response_be_blocked_as_mixed_content(request, &response);
// Step 15.
let mut network_error_response = response
@@ -502,7 +508,7 @@ pub async fn main_fetch(
}
// Step 19. If response is not a network error and any of the following returns blocked
- // TODO: * should internalResponse to request be blocked as mixed content
+ // * should internalResponse to request be blocked as mixed content
// TODO: * should internalResponse to request be blocked by Content Security Policy
// * should internalResponse to request be blocked due to its MIME type
// * should internalResponse to request be blocked due to nosniff
@@ -518,6 +524,10 @@ pub async fn main_fetch(
blocked_error_response =
Response::network_error(NetworkError::Internal("Blocked by mime type".into()));
&blocked_error_response
+ } else if should_replace_with_mixed_content {
+ blocked_error_response =
+ Response::network_error(NetworkError::Internal("Blocked as mixed content".into()));
+ &blocked_error_response
} else {
internal_response
};
@@ -525,7 +535,10 @@ pub async fn main_fetch(
// Step 20. If response’s type is "opaque", internalResponse’s status is 206, internalResponse’s
// range-requested flag is set, and request’s header list does not contain `Range`, then set
// response and internalResponse to a network error.
- let internal_response = if response_type == ResponseType::Opaque &&
+ // Also checking if internal response is a network error to prevent crash from attemtping to
+ // read status of a network error if we blocked the request above.
+ let internal_response = if !internal_response.is_network_error() &&
+ response_type == ResponseType::Opaque &&
internal_response.status.code() == StatusCode::PARTIAL_CONTENT &&
internal_response.range_requested &&
!request.headers.contains_key(RANGE)
@@ -914,6 +927,66 @@ pub fn should_request_be_blocked_due_to_a_bad_port(url: &ServoUrl) -> bool {
false
}
+/// <https://w3c.github.io/webappsec-mixed-content/#should-block-fetch>
+pub fn should_request_be_blocked_as_mixed_content(request: &Request) -> bool {
+ // Step 1. Return allowed if one or more of the following conditions are met:
+ // 1.1. Does settings prohibit mixed security contexts?
+ // returns "Does Not Restrict Mixed Security Contexts" when applied to request’s client.
+ if do_settings_prohibit_mixed_security_contexts(request) ==
+ MixedSecurityProhibited::NotProhibited
+ {
+ return false;
+ }
+
+ // 1.2. request’s URL is a potentially trustworthy URL.
+ if request.url().is_potentially_trustworthy() {
+ return false;
+ }
+
+ // 1.3. The user agent has been instructed to allow mixed content.
+
+ // 1.4. request’s destination is "document", and request’s target browsing context has
+ // no parent browsing context.
+ if request.destination == Destination::Document {
+ // TODO: request's target browsing context has no parent browsing context
+ return false;
+ }
+
+ true
+}
+
+/// <https://w3c.github.io/webappsec-mixed-content/#should-block-response>
+pub fn should_response_be_blocked_as_mixed_content(request: &Request, response: &Response) -> bool {
+ // Step 1. Return allowed if one or more of the following conditions are met:
+ // 1.1. Does settings prohibit mixed security contexts? returns Does Not Restrict Mixed Content
+ // when applied to request’s client.
+ if do_settings_prohibit_mixed_security_contexts(request) ==
+ MixedSecurityProhibited::NotProhibited
+ {
+ return false;
+ }
+
+ // 1.2. response’s url is a potentially trustworthy URL.
+ if response
+ .actual_response()
+ .url()
+ .is_some_and(|response_url| response_url.is_potentially_trustworthy())
+ {
+ return false;
+ }
+
+ // 1.3. TODO: The user agent has been instructed to allow mixed content.
+
+ // 1.4. request’s destination is "document", and request’s target browsing context
+ // has no parent browsing context.
+ if request.destination == Destination::Document {
+ // TODO: if requests target browsing context has no parent browsing context
+ return false;
+ }
+
+ true
+}
+
/// <https://fetch.spec.whatwg.org/#bad-port>
fn is_bad_port(port: u16) -> bool {
static BAD_PORTS: [u16; 78] = [
@@ -983,14 +1056,36 @@ fn should_upgrade_request_to_potentially_trustworty(
request.insecure_requests_policy == InsecureRequestsPolicy::Upgrade
}
-// TODO : Needs to revisit
+#[derive(Debug, PartialEq)]
+pub enum MixedSecurityProhibited {
+ Prohibited,
+ NotProhibited,
+}
+
/// <https://w3c.github.io/webappsec-mixed-content/#categorize-settings-object>
-fn does_settings_prohibit_mixed_security_contexts(url: &ServoUrl) -> bool {
- if url.is_origin_trustworthy() {
- return true;
+fn do_settings_prohibit_mixed_security_contexts(request: &Request) -> MixedSecurityProhibited {
+ if let Origin::Origin(ref origin) = request.origin {
+ // Workers created from a data: url are secure if they were created from secure contexts
+ let is_origin_data_url_worker = matches!(
+ *origin,
+ ImmutableOrigin::Opaque(servo_url::OpaqueOrigin::SecureWorkerFromDataUrl(_))
+ );
+
+ // Step 1. If settings’ origin is a potentially trustworthy origin,
+ // then return "Prohibits Mixed Security Contexts".
+ if origin.is_potentially_trustworthy() || is_origin_data_url_worker {
+ return MixedSecurityProhibited::Prohibited;
+ }
}
- false
+ // Step 2.2. For each navigable navigable in document’s ancestor navigables:
+ // Step 2.2.1. If navigable’s active document's origin is a potentially trustworthy origin,
+ // then return "Prohibits Mixed Security Contexts".
+ if request.has_trustworthy_ancestor_origin {
+ return MixedSecurityProhibited::Prohibited;
+ }
+
+ MixedSecurityProhibited::NotProhibited
}
/// <https://w3c.github.io/webappsec-mixed-content/#upgrade-algorithm>
@@ -1008,12 +1103,14 @@ fn should_upgrade_mixed_content_request(request: &Request) -> bool {
}
// Step 1.3
- if !does_settings_prohibit_mixed_security_contexts(&url) {
+ if do_settings_prohibit_mixed_security_contexts(request) ==
+ MixedSecurityProhibited::NotProhibited
+ {
return false;
}
// Step 1.4 : request’s destination is not "image", "audio", or "video".
- if matches!(
+ if !matches!(
request.destination,
Destination::Audio | Destination::Image | Destination::Video
) {
diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs
index b6f107878a4..609507529dd 100644
--- a/components/net/http_loader.rs
+++ b/components/net/http_loader.rs
@@ -1010,7 +1010,7 @@ pub async fn http_redirect_fetch(
// Step 8: Increase request’s redirect count by 1.
request.redirect_count += 1;
- // Step 7
+ // Step 9
let same_origin = match request.origin {
Origin::Origin(ref origin) => *origin == location_url.origin(),
Origin::Client => panic!(
diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs
index cc426494171..5bfde8dcfc7 100644
--- a/components/script/dom/dedicatedworkerglobalscope.rs
+++ b/components/script/dom/dedicatedworkerglobalscope.rs
@@ -355,6 +355,8 @@ impl DedicatedWorkerGlobalScope {
let referrer = current_global.get_referrer();
let parent = current_global.runtime_handle();
let current_global_https_state = current_global.get_https_state();
+ let current_global_ancestor_trustworthy = current_global.has_trustworthy_ancestor_origin();
+ let is_secure_context = current_global.is_secure_context();
thread::Builder::new()
.name(format!("WW:{}", worker_url.debug_compact()))
@@ -384,8 +386,8 @@ impl DedicatedWorkerGlobalScope {
.use_url_credentials(true)
.pipeline_id(Some(pipeline_id))
.referrer_policy(referrer_policy)
- .referrer_policy(referrer_policy)
.insecure_requests_policy(insecure_requests_policy)
+ .has_trustworthy_ancestor_origin(current_global_ancestor_trustworthy)
.origin(origin);
let runtime = unsafe {
@@ -418,7 +420,12 @@ impl DedicatedWorkerGlobalScope {
// > scope`'s url's scheme is "data", and `inherited origin`
// > otherwise.
if worker_url.scheme() == "data" {
- init.origin = ImmutableOrigin::new_opaque();
+ // Workers created from a data: url are secure if they were created from secure contexts
+ if is_secure_context {
+ init.origin = ImmutableOrigin::new_opaque_data_url_worker();
+ } else {
+ init.origin = ImmutableOrigin::new_opaque();
+ }
}
let global = DedicatedWorkerGlobalScope::new(
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index e7cd9521de2..2e1d3859b4b 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -524,6 +524,8 @@ pub(crate) struct Document {
/// <https://w3c.github.io/webappsec-upgrade-insecure-requests/#insecure-requests-policy>
#[no_trace]
inherited_insecure_requests_policy: Cell<Option<InsecureRequestsPolicy>>,
+ //// <https://w3c.github.io/webappsec-mixed-content/#categorize-settings-object>
+ has_trustworthy_ancestor_origin: Cell<bool>,
/// <https://w3c.github.io/IntersectionObserver/#document-intersectionobservertaskqueued>
intersection_observer_task_queued: Cell<bool>,
/// Active intersection observers that should be processed by this document in
@@ -2479,7 +2481,9 @@ impl Document {
mut request: RequestBuilder,
listener: Listener,
) {
- request = request.insecure_requests_policy(self.insecure_requests_policy());
+ request = request
+ .insecure_requests_policy(self.insecure_requests_policy())
+ .has_trustworthy_ancestor_origin(self.has_trustworthy_ancestor_or_current_origin());
let callback = NetworkListener {
context: std::sync::Arc::new(Mutex::new(listener)),
task_source: self
@@ -2498,7 +2502,9 @@ impl Document {
mut request: RequestBuilder,
listener: Listener,
) {
- request = request.insecure_requests_policy(self.insecure_requests_policy());
+ request = request
+ .insecure_requests_policy(self.insecure_requests_policy())
+ .has_trustworthy_ancestor_origin(self.has_trustworthy_ancestor_or_current_origin());
let callback = NetworkListener {
context: std::sync::Arc::new(Mutex::new(listener)),
task_source: self
@@ -3735,6 +3741,7 @@ impl Document {
is_initial_about_blank: bool,
allow_declarative_shadow_roots: bool,
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
+ has_trustworthy_ancestor_origin: bool,
) -> Document {
let url = url.unwrap_or_else(|| ServoUrl::parse("about:blank").unwrap());
@@ -3895,6 +3902,7 @@ impl Document {
is_initial_about_blank: Cell::new(is_initial_about_blank),
allow_declarative_shadow_roots: Cell::new(allow_declarative_shadow_roots),
inherited_insecure_requests_policy: Cell::new(inherited_insecure_requests_policy),
+ has_trustworthy_ancestor_origin: Cell::new(has_trustworthy_ancestor_origin),
intersection_observer_task_queued: Cell::new(false),
intersection_observers: Default::default(),
active_keyboard_modifiers: Cell::new(Modifiers::empty()),
@@ -4052,6 +4060,7 @@ impl Document {
is_initial_about_blank: bool,
allow_declarative_shadow_roots: bool,
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
+ has_trustworthy_ancestor_origin: bool,
can_gc: CanGc,
) -> DomRoot<Document> {
Self::new_with_proto(
@@ -4072,6 +4081,7 @@ impl Document {
is_initial_about_blank,
allow_declarative_shadow_roots,
inherited_insecure_requests_policy,
+ has_trustworthy_ancestor_origin,
can_gc,
)
}
@@ -4095,6 +4105,7 @@ impl Document {
is_initial_about_blank: bool,
allow_declarative_shadow_roots: bool,
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
+ has_trustworthy_ancestor_origin: bool,
can_gc: CanGc,
) -> DomRoot<Document> {
let document = reflect_dom_object_with_proto(
@@ -4115,6 +4126,7 @@ impl Document {
is_initial_about_blank,
allow_declarative_shadow_roots,
inherited_insecure_requests_policy,
+ has_trustworthy_ancestor_origin,
)),
window,
proto,
@@ -4248,6 +4260,7 @@ impl Document {
false,
self.allow_declarative_shadow_roots(),
Some(self.insecure_requests_policy()),
+ self.has_trustworthy_ancestor_or_current_origin(),
can_gc,
);
new_doc
@@ -4795,6 +4808,15 @@ impl Document {
pub fn set_allow_declarative_shadow_roots(&self, value: bool) {
self.allow_declarative_shadow_roots.set(value)
}
+
+ pub fn has_trustworthy_ancestor_origin(&self) -> bool {
+ self.has_trustworthy_ancestor_origin.get()
+ }
+
+ pub fn has_trustworthy_ancestor_or_current_origin(&self) -> bool {
+ self.has_trustworthy_ancestor_origin.get() ||
+ self.origin().immutable().is_potentially_trustworthy()
+ }
}
#[allow(non_snake_case)]
@@ -4825,6 +4847,7 @@ impl DocumentMethods<crate::DomTypeHolder> for Document {
false,
doc.allow_declarative_shadow_roots(),
Some(doc.insecure_requests_policy()),
+ doc.has_trustworthy_ancestor_or_current_origin(),
can_gc,
))
}
diff --git a/components/script/dom/domimplementation.rs b/components/script/dom/domimplementation.rs
index 09916e9a4dc..4adae2f4229 100644
--- a/components/script/dom/domimplementation.rs
+++ b/components/script/dom/domimplementation.rs
@@ -110,6 +110,7 @@ impl DOMImplementationMethods<crate::DomTypeHolder> for DOMImplementation {
DocumentSource::NotFromParser,
loader,
Some(self.document.insecure_requests_policy()),
+ self.document.has_trustworthy_ancestor_or_current_origin(),
can_gc,
);
@@ -176,6 +177,7 @@ impl DOMImplementationMethods<crate::DomTypeHolder> for DOMImplementation {
false,
self.document.allow_declarative_shadow_roots(),
Some(self.document.insecure_requests_policy()),
+ self.document.has_trustworthy_ancestor_or_current_origin(),
can_gc,
);
diff --git a/components/script/dom/domparser.rs b/components/script/dom/domparser.rs
index 42782420bda..85d7cd0870f 100644
--- a/components/script/dom/domparser.rs
+++ b/components/script/dom/domparser.rs
@@ -90,6 +90,7 @@ impl DOMParserMethods<crate::DomTypeHolder> for DOMParser {
false,
false,
Some(doc.insecure_requests_policy()),
+ doc.has_trustworthy_ancestor_or_current_origin(),
can_gc,
);
ServoParser::parse_html_document(&document, Some(s), url, can_gc);
@@ -114,6 +115,7 @@ impl DOMParserMethods<crate::DomTypeHolder> for DOMParser {
false,
false,
Some(doc.insecure_requests_policy()),
+ doc.has_trustworthy_ancestor_or_current_origin(),
can_gc,
);
ServoParser::parse_xml_document(&document, Some(s), url, can_gc);
diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs
index 8b3dc4d5113..f5b2124eb2e 100644
--- a/components/script/dom/eventsource.rs
+++ b/components/script/dom/eventsource.rs
@@ -561,6 +561,7 @@ impl EventSourceMethods<crate::DomTypeHolder> for EventSource {
Some(true),
global.get_referrer(),
global.insecure_requests_policy(),
+ global.has_trustworthy_ancestor_or_current_origin(),
)
.origin(global.origin().immutable().clone())
.pipeline_id(Some(global.pipeline_id()));
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs
index a3f4f929ef8..d0d7830e2bb 100644
--- a/components/script/dom/globalscope.rs
+++ b/components/script/dom/globalscope.rs
@@ -2386,6 +2386,21 @@ impl GlobalScope {
InsecureRequestsPolicy::DoNotUpgrade
}
+ /// Whether this document has ancestor navigables that are trustworthy
+ pub(crate) fn has_trustworthy_ancestor_origin(&self) -> bool {
+ self.downcast::<Window>()
+ .is_some_and(|window| window.Document().has_trustworthy_ancestor_origin())
+ }
+
+ // Whether this document has a trustworthy origin or has trustowrthy ancestor navigables
+ pub(crate) fn has_trustworthy_ancestor_or_current_origin(&self) -> bool {
+ self.downcast::<Window>().is_some_and(|window| {
+ window
+ .Document()
+ .has_trustworthy_ancestor_or_current_origin()
+ })
+ }
+
/// <https://html.spec.whatwg.org/multipage/#report-the-error>
pub(crate) fn report_an_error(&self, error_info: ErrorInfo, value: HandleValue, can_gc: CanGc) {
// Step 1.
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs
index e4b16a73cb4..fd85e3fd1a9 100644
--- a/components/script/dom/htmlformelement.rs
+++ b/components/script/dom/htmlformelement.rs
@@ -867,6 +867,7 @@ impl HTMLFormElement {
target_document.get_referrer_policy(),
Some(target_window.as_global_scope().is_secure_context()),
Some(target_document.insecure_requests_policy()),
+ target_document.has_trustworthy_ancestor_origin(),
);
// Step 22
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs
index bfef6cebbe6..04127ef1b17 100644
--- a/components/script/dom/htmliframeelement.rs
+++ b/components/script/dom/htmliframeelement.rs
@@ -271,6 +271,7 @@ impl HTMLIFrameElement {
document.get_referrer_policy(),
Some(window.as_global_scope().is_secure_context()),
Some(document.insecure_requests_policy()),
+ document.has_trustworthy_ancestor_or_current_origin(),
);
let element = self.upcast::<Element>();
load_data.srcdoc = String::from(element.get_string_attribute(&local_name!("srcdoc")));
@@ -362,6 +363,7 @@ impl HTMLIFrameElement {
referrer_policy,
Some(window.as_global_scope().is_secure_context()),
Some(document.insecure_requests_policy()),
+ document.has_trustworthy_ancestor_or_current_origin(),
);
let pipeline_id = self.pipeline_id();
@@ -407,6 +409,7 @@ impl HTMLIFrameElement {
document.get_referrer_policy(),
Some(window.as_global_scope().is_secure_context()),
Some(document.insecure_requests_policy()),
+ document.has_trustworthy_ancestor_or_current_origin(),
);
let browsing_context_id = BrowsingContextId::new();
let webview_id = window.window_proxy().webview_id();
diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs
index ee23270a549..e7990561a55 100644
--- a/components/script/dom/htmlimageelement.rs
+++ b/components/script/dom/htmlimageelement.rs
@@ -424,6 +424,7 @@ impl HTMLImageElement {
None,
document.global().get_referrer(),
document.insecure_requests_policy(),
+ document.has_trustworthy_ancestor_or_current_origin(),
)
.origin(document.origin().immutable().clone())
.pipeline_id(Some(document.global().pipeline_id()))
diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs
index aab9f28b48e..427153fefd9 100644
--- a/components/script/dom/htmllinkelement.rs
+++ b/components/script/dom/htmllinkelement.rs
@@ -82,6 +82,7 @@ struct LinkProcessingOptions {
source_set: Option<()>,
base_url: ServoUrl,
insecure_requests_policy: InsecureRequestsPolicy,
+ has_trustworthy_ancestor_origin: bool,
// Some fields that we don't need yet are missing
}
@@ -335,6 +336,7 @@ impl HTMLLinkElement {
source_set: None, // FIXME
base_url: document.borrow().base_url(),
insecure_requests_policy: document.insecure_requests_policy(),
+ has_trustworthy_ancestor_origin: document.has_trustworthy_ancestor_or_current_origin(),
};
// Step 3. If el has an href attribute, then set options's href to the value of el's href attribute.
@@ -669,6 +671,7 @@ impl LinkProcessingOptions {
None,
Referrer::NoReferrer,
self.insecure_requests_policy,
+ self.has_trustworthy_ancestor_origin,
)
.integrity_metadata(self.integrity)
.policy_container(self.policy_container)
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index 062f1749d28..a608ba40c92 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -894,6 +894,7 @@ impl HTMLMediaElement {
None,
self.global().get_referrer(),
document.insecure_requests_policy(),
+ document.has_trustworthy_ancestor_or_current_origin(),
)
.headers(headers)
.origin(document.origin().immutable().clone())
diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs
index 61047817594..02c2fd4c73a 100644
--- a/components/script/dom/htmlscriptelement.rs
+++ b/components/script/dom/htmlscriptelement.rs
@@ -558,6 +558,7 @@ impl PreInvoke for ClassicContext {}
/// Steps 1-2 of <https://html.spec.whatwg.org/multipage/#fetch-a-classic-script>
// This function is also used to prefetch a script in `script::dom::servoparser::prefetch`.
+#[allow(clippy::too_many_arguments)]
pub(crate) fn script_fetch_request(
webview_id: WebViewId,
url: ServoUrl,
@@ -566,6 +567,7 @@ pub(crate) fn script_fetch_request(
pipeline_id: PipelineId,
options: ScriptFetchOptions,
insecure_requests_policy: InsecureRequestsPolicy,
+ has_trustworthy_ancestor_origin: bool,
) -> RequestBuilder {
// We intentionally ignore options' credentials_mode member for classic scripts.
// The mode is initialized by create_a_potential_cors_request.
@@ -577,6 +579,7 @@ pub(crate) fn script_fetch_request(
None,
options.referrer,
insecure_requests_policy,
+ has_trustworthy_ancestor_origin,
)
.origin(origin)
.pipeline_id(Some(pipeline_id))
@@ -605,6 +608,7 @@ fn fetch_a_classic_script(
script.global().pipeline_id(),
options.clone(),
doc.insecure_requests_policy(),
+ doc.has_trustworthy_ancestor_origin(),
);
let request = doc.prepare_request(request);
diff --git a/components/script/dom/location.rs b/components/script/dom/location.rs
index 3241717fdf8..eabf9c83f81 100644
--- a/components/script/dom/location.rs
+++ b/components/script/dom/location.rs
@@ -126,6 +126,7 @@ impl Location {
referrer_policy,
None, // Top navigation doesn't inherit secure context
Some(source_document.insecure_requests_policy()),
+ source_document.has_trustworthy_ancestor_origin(),
);
self.window
.load_url(history_handling, reload_triggered, load_data, can_gc);
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index 0caac6be09e..eff078c49c4 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -2661,6 +2661,7 @@ impl Node {
false,
document.allow_declarative_shadow_roots(),
Some(document.insecure_requests_policy()),
+ document.has_trustworthy_ancestor_or_current_origin(),
can_gc,
);
DomRoot::upcast::<Node>(document)
diff --git a/components/script/dom/notification.rs b/components/script/dom/notification.rs
index 0cdf0a74d69..11d786c8216 100644
--- a/components/script/dom/notification.rs
+++ b/components/script/dom/notification.rs
@@ -820,6 +820,7 @@ impl Notification {
None,
global.get_referrer(),
global.insecure_requests_policy(),
+ global.has_trustworthy_ancestor_or_current_origin(),
)
.origin(global.origin().immutable().clone())
.pipeline_id(Some(global.pipeline_id()))
diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs
index 406b6b4222d..f7d73e6a2b4 100644
--- a/components/script/dom/request.rs
+++ b/components/script/dom/request.rs
@@ -113,6 +113,7 @@ fn net_request_from_global(global: &GlobalScope, url: ServoUrl) -> NetTraitsRequ
.pipeline_id(Some(global.pipeline_id()))
.https_state(global.get_https_state())
.insecure_requests_policy(global.insecure_requests_policy())
+ .has_trustworthy_ancestor_origin(global.has_trustworthy_ancestor_or_current_origin())
.build()
}
diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs
index a3881ef7f2e..0cc0854e34a 100644
--- a/components/script/dom/servoparser/mod.rs
+++ b/components/script/dom/servoparser/mod.rs
@@ -228,6 +228,7 @@ impl ServoParser {
false,
allow_declarative_shadow_roots,
Some(context_document.insecure_requests_policy()),
+ context_document.has_trustworthy_ancestor_or_current_origin(),
can_gc,
);
diff --git a/components/script/dom/servoparser/prefetch.rs b/components/script/dom/servoparser/prefetch.rs
index f2873406cd5..250b92f8c8b 100644
--- a/components/script/dom/servoparser/prefetch.rs
+++ b/components/script/dom/servoparser/prefetch.rs
@@ -73,6 +73,7 @@ impl Tokenizer {
// block the main parser.
prefetching: Cell::new(false),
insecure_requests_policy: document.insecure_requests_policy(),
+ has_trustworthy_ancestor_origin: document.has_trustworthy_ancestor_or_current_origin(),
};
let options = Default::default();
let inner = TraceableTokenizer(HtmlTokenizer::new(sink, options));
@@ -105,6 +106,7 @@ struct PrefetchSink {
prefetching: Cell<bool>,
#[no_trace]
insecure_requests_policy: InsecureRequestsPolicy,
+ has_trustworthy_ancestor_origin: bool,
}
/// The prefetch tokenizer produces trivial results
@@ -146,6 +148,7 @@ impl TokenSink for PrefetchSink {
parser_metadata: ParserMetadata::ParserInserted,
},
self.insecure_requests_policy,
+ self.has_trustworthy_ancestor_origin,
);
let _ = self
.resource_threads
@@ -164,6 +167,7 @@ impl TokenSink for PrefetchSink {
None,
self.referrer.clone(),
self.insecure_requests_policy,
+ self.has_trustworthy_ancestor_origin,
)
.origin(self.origin.clone())
.pipeline_id(Some(self.pipeline_id))
@@ -198,6 +202,7 @@ impl TokenSink for PrefetchSink {
None,
self.referrer.clone(),
self.insecure_requests_policy,
+ self.has_trustworthy_ancestor_origin,
)
.origin(self.origin.clone())
.pipeline_id(Some(self.pipeline_id))
diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs
index 760318771fa..4cfb143a10d 100644
--- a/components/script/dom/websocket.rs
+++ b/components/script/dom/websocket.rs
@@ -261,6 +261,7 @@ impl WebSocketMethods<crate::DomTypeHolder> for WebSocket {
let request = RequestBuilder::new(global.webview_id(), url_record, Referrer::NoReferrer)
.origin(global.origin().immutable().clone())
.insecure_requests_policy(global.insecure_requests_policy())
+ .has_trustworthy_ancestor_origin(global.has_trustworthy_ancestor_or_current_origin())
.mode(RequestMode::WebSocket { protocols })
.service_workers_mode(ServiceWorkersMode::None)
.credentials_mode(CredentialsMode::Include)
diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs
index feeece3a8e8..f4e429ee731 100644
--- a/components/script/dom/windowproxy.rs
+++ b/components/script/dom/windowproxy.rs
@@ -307,6 +307,7 @@ impl WindowProxy {
document.get_referrer_policy(),
None, // Doesn't inherit secure context
None,
+ false,
);
let load_info = AuxiliaryWebViewCreationRequest {
load_data: load_data.clone(),
@@ -485,6 +486,11 @@ impl WindowProxy {
Some(target_document) => target_document,
None => return Ok(None),
};
+ let has_trustworthy_ancestor_origin = if new {
+ target_document.has_trustworthy_ancestor_or_current_origin()
+ } else {
+ false
+ };
let target_window = target_document.window();
// Step 13, and 14.4, will have happened elsewhere,
// since we've created a new browsing context and loaded it with about:blank.
@@ -517,6 +523,7 @@ impl WindowProxy {
referrer_policy,
Some(secure),
Some(target_document.insecure_requests_policy()),
+ has_trustworthy_ancestor_origin,
);
let history_handling = if new {
NavigationHistoryBehavior::Replace
diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs
index f084d429730..6e70ffe34e0 100644
--- a/components/script/dom/workerglobalscope.rs
+++ b/components/script/dom/workerglobalscope.rs
@@ -296,6 +296,9 @@ impl WorkerGlobalScopeMethods<crate::DomTypeHolder> for WorkerGlobalScope {
.use_url_credentials(true)
.origin(global_scope.origin().immutable().clone())
.insecure_requests_policy(self.insecure_requests_policy())
+ .has_trustworthy_ancestor_origin(
+ global_scope.has_trustworthy_ancestor_or_current_origin(),
+ )
.pipeline_id(Some(self.upcast::<GlobalScope>().pipeline_id()));
let (url, source) = match fetch::load_whole_resource(
diff --git a/components/script/dom/xmldocument.rs b/components/script/dom/xmldocument.rs
index e438c7780b8..c21a0ad99ee 100644
--- a/components/script/dom/xmldocument.rs
+++ b/components/script/dom/xmldocument.rs
@@ -43,6 +43,7 @@ impl XMLDocument {
source: DocumentSource,
doc_loader: DocumentLoader,
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
+ has_trustworthy_ancestor_origin: bool,
) -> XMLDocument {
XMLDocument {
document: Document::new_inherited(
@@ -62,6 +63,7 @@ impl XMLDocument {
false,
false,
inherited_insecure_requests_policy,
+ has_trustworthy_ancestor_origin,
),
}
}
@@ -79,6 +81,7 @@ impl XMLDocument {
source: DocumentSource,
doc_loader: DocumentLoader,
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
+ has_trustworthy_ancestor_origin: bool,
can_gc: CanGc,
) -> DomRoot<XMLDocument> {
let doc = reflect_dom_object(
@@ -94,6 +97,7 @@ impl XMLDocument {
source,
doc_loader,
inherited_insecure_requests_policy,
+ has_trustworthy_ancestor_origin,
)),
window,
can_gc,
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs
index 10836cd12c9..aa634d61ccc 100644
--- a/components/script/dom/xmlhttprequest.rs
+++ b/components/script/dom/xmlhttprequest.rs
@@ -688,6 +688,7 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest {
.origin(self.global().origin().immutable().clone())
.referrer_policy(self.referrer_policy)
.insecure_requests_policy(self.global().insecure_requests_policy())
+ .has_trustworthy_ancestor_origin(self.global().has_trustworthy_ancestor_or_current_origin())
.pipeline_id(Some(self.global().pipeline_id()));
// step 4 (second half)
@@ -1515,6 +1516,7 @@ impl XMLHttpRequest {
false,
false,
Some(doc.insecure_requests_policy()),
+ doc.has_trustworthy_ancestor_origin(),
can_gc,
)
}
diff --git a/components/script/fetch.rs b/components/script/fetch.rs
index ca46eb6ae60..92610febc43 100644
--- a/components/script/fetch.rs
+++ b/components/script/fetch.rs
@@ -123,6 +123,7 @@ fn request_init_from_request(request: NetTraitsRequest) -> RequestBuilder {
initiator: request.initiator,
policy_container: request.policy_container,
insecure_requests_policy: request.insecure_requests_policy,
+ has_trustworthy_ancestor_origin: request.has_trustworthy_ancestor_origin,
https_state: request.https_state,
response_tainting: request.response_tainting,
crash: None,
@@ -374,6 +375,7 @@ pub(crate) fn load_whole_resource(
}
/// <https://html.spec.whatwg.org/multipage/#create-a-potential-cors-request>
+#[allow(clippy::too_many_arguments)]
pub(crate) fn create_a_potential_cors_request(
webview_id: Option<WebViewId>,
url: ServoUrl,
@@ -382,6 +384,7 @@ pub(crate) fn create_a_potential_cors_request(
same_origin_fallback: Option<bool>,
referrer: Referrer,
insecure_requests_policy: InsecureRequestsPolicy,
+ has_trustworthy_ancestor_origin: bool,
) -> RequestBuilder {
RequestBuilder::new(webview_id, url, referrer)
// https://html.spec.whatwg.org/multipage/#create-a-potential-cors-request
@@ -401,4 +404,5 @@ pub(crate) fn create_a_potential_cors_request(
.destination(destination)
.use_url_credentials(true)
.insecure_requests_policy(insecure_requests_policy)
+ .has_trustworthy_ancestor_origin(has_trustworthy_ancestor_origin)
}
diff --git a/components/script/links.rs b/components/script/links.rs
index f997f50ebc2..55c7435cdb9 100644
--- a/components/script/links.rs
+++ b/components/script/links.rs
@@ -440,6 +440,7 @@ pub(crate) fn follow_hyperlink(
referrer_policy,
Some(secure),
Some(document.insecure_requests_policy()),
+ document.has_trustworthy_ancestor_origin(),
);
let target = Trusted::new(target_window);
let task = task!(navigate_follow_hyperlink: move || {
diff --git a/components/script/navigation.rs b/components/script/navigation.rs
index 2c22e25c123..4a960299813 100644
--- a/components/script/navigation.rs
+++ b/components/script/navigation.rs
@@ -212,6 +212,7 @@ impl InProgressLoad {
.inherited_insecure_requests_policy
.unwrap_or(InsecureRequestsPolicy::DoNotUpgrade),
)
+ .has_trustworthy_ancestor_origin(self.load_data.has_trustworthy_ancestor_origin)
.headers(self.load_data.headers.clone())
.body(self.load_data.data.clone())
.redirect_mode(RedirectMode::Manual)
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index 51b48499844..5b5aa4b9254 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -3193,6 +3193,7 @@ impl ScriptThread {
is_initial_about_blank,
true,
incomplete.load_data.inherited_insecure_requests_policy,
+ incomplete.load_data.has_trustworthy_ancestor_origin,
can_gc,
);
diff --git a/components/script/serviceworker_manager.rs b/components/script/serviceworker_manager.rs
index dba412d9a42..d4089714031 100644
--- a/components/script/serviceworker_manager.rs
+++ b/components/script/serviceworker_manager.rs
@@ -321,7 +321,7 @@ impl ServiceWorkerManager {
/// <https://w3c.github.io/ServiceWorker/#register-algorithm>
fn handle_register_job(&mut self, mut job: Job) {
- if !job.script_url.is_origin_trustworthy() {
+ if !job.script_url.origin().is_potentially_trustworthy() {
// Step 1.1
let _ = job
.client
diff --git a/components/script/stylesheet_loader.rs b/components/script/stylesheet_loader.rs
index 6570c3df284..6290d2709cc 100644
--- a/components/script/stylesheet_loader.rs
+++ b/components/script/stylesheet_loader.rs
@@ -351,6 +351,7 @@ impl StylesheetLoader<'_> {
None,
self.elem.global().get_referrer(),
document.insecure_requests_policy(),
+ document.has_trustworthy_ancestor_or_current_origin(),
)
.origin(document.origin().immutable().clone())
.pipeline_id(Some(self.elem.global().pipeline_id()))
diff --git a/components/shared/net/request.rs b/components/shared/net/request.rs
index 58cba5cba5c..8dec7668077 100644
--- a/components/shared/net/request.rs
+++ b/components/shared/net/request.rs
@@ -292,6 +292,7 @@ pub struct RequestBuilder {
/// <https://fetch.spec.whatwg.org/#concept-request-policy-container>
pub policy_container: RequestPolicyContainer,
pub insecure_requests_policy: InsecureRequestsPolicy,
+ pub has_trustworthy_ancestor_origin: bool,
/// <https://fetch.spec.whatwg.org/#concept-request-referrer>
pub referrer: Referrer,
@@ -344,6 +345,7 @@ impl RequestBuilder {
origin: ImmutableOrigin::new_opaque(),
policy_container: RequestPolicyContainer::default(),
insecure_requests_policy: InsecureRequestsPolicy::DoNotUpgrade,
+ has_trustworthy_ancestor_origin: false,
referrer,
referrer_policy: ReferrerPolicy::EmptyString,
pipeline_id: None,
@@ -493,6 +495,14 @@ impl RequestBuilder {
self
}
+ pub fn has_trustworthy_ancestor_origin(
+ mut self,
+ has_trustworthy_ancestor_origin: bool,
+ ) -> RequestBuilder {
+ self.has_trustworthy_ancestor_origin = has_trustworthy_ancestor_origin;
+ self
+ }
+
/// <https://fetch.spec.whatwg.org/#request-service-workers-mode>
pub fn service_workers_mode(
mut self,
@@ -546,6 +556,7 @@ impl RequestBuilder {
request.crash = self.crash;
request.policy_container = self.policy_container;
request.insecure_requests_policy = self.insecure_requests_policy;
+ request.has_trustworthy_ancestor_origin = self.has_trustworthy_ancestor_origin;
request
}
}
@@ -621,6 +632,7 @@ pub struct Request {
pub policy_container: RequestPolicyContainer,
/// <https://w3c.github.io/webappsec-upgrade-insecure-requests/#insecure-requests-policy>
pub insecure_requests_policy: InsecureRequestsPolicy,
+ pub has_trustworthy_ancestor_origin: bool,
pub https_state: HttpsState,
/// Servo internal: if crash details are present, trigger a crash error page with these details.
pub crash: Option<String>,
@@ -668,6 +680,7 @@ impl Request {
response_tainting: ResponseTainting::Basic,
policy_container: RequestPolicyContainer::Client,
insecure_requests_policy: InsecureRequestsPolicy::DoNotUpgrade,
+ has_trustworthy_ancestor_origin: false,
https_state,
crash: None,
}
diff --git a/components/shared/script/lib.rs b/components/shared/script/lib.rs
index f73deb29e7f..91e4ca33dc4 100644
--- a/components/shared/script/lib.rs
+++ b/components/shared/script/lib.rs
@@ -117,7 +117,8 @@ pub struct LoadData {
pub inherited_secure_context: Option<bool>,
/// The inherited policy for upgrading insecure requests; None if not inherited.
pub inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
-
+ /// Whether the page's ancestors have potentially trustworthy origin
+ pub has_trustworthy_ancestor_origin: bool,
/// Servo internal: if crash details are present, trigger a crash error page with these details.
pub crash: Option<String>,
}
@@ -134,6 +135,7 @@ pub enum JsEvalResult {
impl LoadData {
/// Create a new `LoadData` object.
+ #[allow(clippy::too_many_arguments)]
pub fn new(
load_origin: LoadOrigin,
url: ServoUrl,
@@ -142,6 +144,7 @@ impl LoadData {
referrer_policy: ReferrerPolicy,
inherited_secure_context: Option<bool>,
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
+ has_trustworthy_ancestor_origin: bool,
) -> LoadData {
LoadData {
load_origin,
@@ -157,6 +160,7 @@ impl LoadData {
inherited_secure_context,
crash: None,
inherited_insecure_requests_policy,
+ has_trustworthy_ancestor_origin,
}
}
}
diff --git a/components/url/lib.rs b/components/url/lib.rs
index 17a8e6523a4..8aa04fd5ae4 100644
--- a/components/url/lib.rs
+++ b/components/url/lib.rs
@@ -224,33 +224,7 @@ impl ServoUrl {
return true;
}
// Step 3
- self.is_origin_trustworthy()
- }
-
- /// <https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy>
- pub fn is_origin_trustworthy(&self) -> bool {
- // Step 1
- if !self.origin().is_tuple() {
- return false;
- }
-
- // Step 3
- if self.scheme() == "https" || self.scheme() == "wss" {
- true
- // Steps 4-5
- } else if self.host().is_some() {
- let host = self.host_str().unwrap();
- // Step 4
- if let Ok(ip_addr) = host.parse::<IpAddr>() {
- ip_addr.is_loopback()
- // Step 5
- } else {
- host == "localhost" || host.ends_with(".localhost")
- }
- // Step 6
- } else {
- self.scheme() == "file"
- }
+ self.origin().is_potentially_trustworthy()
}
}
diff --git a/components/url/origin.rs b/components/url/origin.rs
index ede6b134135..a19d45b966c 100644
--- a/components/url/origin.rs
+++ b/components/url/origin.rs
@@ -3,6 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::cell::RefCell;
+use std::net::IpAddr;
use std::rc::Rc;
use malloc_size_of::malloc_size_of_is_0;
@@ -39,7 +40,14 @@ impl ImmutableOrigin {
/// Creates a new opaque origin that is only equal to itself.
pub fn new_opaque() -> ImmutableOrigin {
- ImmutableOrigin::Opaque(OpaqueOrigin(servo_rand::random_uuid()))
+ ImmutableOrigin::Opaque(OpaqueOrigin::Opaque(servo_rand::random_uuid()))
+ }
+
+ // For use in mixed security context tests because data: URL workers inherit contexts
+ pub fn new_opaque_data_url_worker() -> ImmutableOrigin {
+ ImmutableOrigin::Opaque(OpaqueOrigin::SecureWorkerFromDataUrl(
+ servo_rand::random_uuid(),
+ ))
}
pub fn scheme(&self) -> Option<&str> {
@@ -79,6 +87,43 @@ impl ImmutableOrigin {
}
}
+ /// <https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy>
+ pub fn is_potentially_trustworthy(&self) -> bool {
+ // 1. If origin is an opaque origin return "Not Trustworthy"
+ if matches!(self, ImmutableOrigin::Opaque(_)) {
+ return false;
+ }
+
+ if let ImmutableOrigin::Tuple(scheme, host, _) = self {
+ // 3. If origin’s scheme is either "https" or "wss", return "Potentially Trustworthy"
+ if scheme == "https" || scheme == "wss" {
+ return true;
+ }
+ // 6. If origin’s scheme is "file", return "Potentially Trustworthy".
+ if scheme == "file" {
+ return true;
+ }
+
+ // 4. If origin’s host matches one of the CIDR notations 127.0.0.0/8 or ::1/128,
+ // return "Potentially Trustworthy".
+ if let Ok(ip_addr) = host.to_string().parse::<IpAddr>() {
+ return ip_addr.is_loopback();
+ }
+ // 5. If the user agent conforms to the name resolution rules in
+ // [let-localhost-be-localhost] and one of the following is true:
+ // * origin’s host is "localhost" or "localhost."
+ // * origin’s host ends with ".localhost" or ".localhost."
+ // then return "Potentially Trustworthy".
+ if let Host::Domain(domain) = host {
+ if domain == "localhost" || domain.ends_with(".localhost") {
+ return true;
+ }
+ }
+ }
+ // 9. Return "Not Trustworthy".
+ false
+ }
+
/// <https://html.spec.whatwg.org/multipage/#ascii-serialisation-of-an-origin>
pub fn ascii_serialization(&self) -> String {
self.clone().into_url_origin().ascii_serialization()
@@ -87,8 +132,13 @@ impl ImmutableOrigin {
/// Opaque identifier for URLs that have file or other schemes
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
-pub struct OpaqueOrigin(Uuid);
-
+pub enum OpaqueOrigin {
+ Opaque(Uuid),
+ // Workers created from `data:` urls will have opaque origins but need to be treated
+ // as inheriting the secure context they were created in. This tracks that the origin
+ // was created in such a context
+ SecureWorkerFromDataUrl(Uuid),
+}
malloc_size_of_is_0!(OpaqueOrigin);
/// A representation of an [origin](https://html.spec.whatwg.org/multipage/#origin-2).