aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorSimon Wülker <simon.wuelker@arcor.de>2025-03-10 10:25:34 +0100
committerGitHub <noreply@github.com>2025-03-10 09:25:34 +0000
commit1b6b21cb8579622955e2a25c59ebb2bb0875b169 (patch)
tree922bc204a8fbb0958493e594d33b2d2e103f295f /components/script
parentce4ba309924ffa35e0dd4309527586b8f0c22b75 (diff)
downloadservo-1b6b21cb8579622955e2a25c59ebb2bb0875b169.tar.gz
servo-1b6b21cb8579622955e2a25c59ebb2bb0875b169.zip
Implement `nonce` attribute to pass more CSP checks (#35876)
* Add doc comments to RequestBuilder fields/methods Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Implement Request::cryptographic_nonce_metadata Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Implement HTMLOrSVGElement::nonce Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Set request cryptographic nonce metadata for link elements Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Set request's cryptographic nonce when fetching scripts Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Forward request nonce to rust-content-security-policy Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Update WPT expectations Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> --------- Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/htmlelement.rs8
-rw-r--r--components/script/dom/htmllinkelement.rs8
-rw-r--r--components/script/dom/htmlscriptelement.rs4
-rw-r--r--components/script/dom/servoparser/prefetch.rs6
-rw-r--r--components/script/dom/svgelement.rs9
-rw-r--r--components/script/fetch.rs1
6 files changed, 32 insertions, 4 deletions
diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs
index 6bf01535a10..1f0d1f223fb 100644
--- a/components/script/dom/htmlelement.rs
+++ b/components/script/dom/htmlelement.rs
@@ -641,6 +641,14 @@ impl HTMLElementMethods<crate::DomTypeHolder> for HTMLElement {
Ok(internals)
}
+ // FIXME: The nonce should be stored in an internal slot instead of an
+ // attribute (https://html.spec.whatwg.org/multipage/#cryptographicnonce)
+ // https://html.spec.whatwg.org/multipage/#dom-noncedelement-nonce
+ make_getter!(Nonce, "nonce");
+
+ // https://html.spec.whatwg.org/multipage/#dom-noncedelement-nonce
+ make_setter!(SetNonce, "nonce");
+
// https://html.spec.whatwg.org/multipage/#dom-fe-autofocus
fn Autofocus(&self) -> bool {
self.element.has_attribute(&local_name!("autofocus"))
diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs
index a321cd25fc9..bf5939138f5 100644
--- a/components/script/dom/htmllinkelement.rs
+++ b/components/script/dom/htmllinkelement.rs
@@ -30,11 +30,11 @@ use style::parser::ParserContext as CssParserContext;
use style::stylesheets::{CssRuleType, Origin, Stylesheet, UrlExtraData};
use style_traits::ParsingMode;
-use super::types::{EventTarget, GlobalScope};
use crate::dom::attr::Attr;
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::DOMTokenListBinding::DOMTokenList_Binding::DOMTokenListMethods;
use crate::dom::bindings::codegen::Bindings::HTMLLinkElementBinding::HTMLLinkElementMethods;
+use crate::dom::bindings::codegen::GenericBindings::HTMLElementBinding::HTMLElement_Binding::HTMLElementMethods;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::refcounted::Trusted;
use crate::dom::bindings::reflector::DomGlobal;
@@ -52,6 +52,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{BindContext, Node, NodeTraits, UnbindContext};
use crate::dom::performanceresourcetiming::InitiatorType;
use crate::dom::stylesheet::StyleSheet as DOMStyleSheet;
+use crate::dom::types::{EventTarget, GlobalScope};
use crate::dom::virtualmethods::VirtualMethods;
use crate::fetch::create_a_potential_cors_request;
use crate::links::LinkRelations;
@@ -74,6 +75,7 @@ struct LinkProcessingOptions {
destination: Option<Destination>,
integrity: String,
link_type: String,
+ cryptographic_nonce_metadata: String,
cross_origin: Option<CorsSettings>,
referrer_policy: ReferrerPolicy,
policy_container: PolicyContainer,
@@ -324,6 +326,7 @@ impl HTMLLinkElement {
destination: Some(destination),
integrity: String::new(),
link_type: String::new(),
+ cryptographic_nonce_metadata: self.upcast::<HTMLElement>().Nonce().into(),
cross_origin: cors_setting_for_element(element),
referrer_policy: referrer_policy_for_element(element),
policy_container: document.policy_container().to_owned(),
@@ -651,7 +654,7 @@ impl LinkProcessingOptions {
// url, options's destination, and options's crossorigin.
// Step 6. Set request's policy container to options's policy container.
// Step 7. Set request's integrity metadata to options's integrity.
- // FIXME: Step 8. Set request's cryptographic nonce metadata to options's cryptographic nonce metadata.
+ // Step 8. Set request's cryptographic nonce metadata to options's cryptographic nonce metadata.
// Step 9. Set request's referrer policy to options's referrer policy.
// FIXME: Step 10. Set request's client to options's environment.
// FIXME: Step 11. Set request's priority to options's fetch priority.
@@ -667,6 +670,7 @@ impl LinkProcessingOptions {
)
.integrity_metadata(self.integrity)
.policy_container(self.policy_container)
+ .cryptographic_nonce_metadata(self.cryptographic_nonce_metadata)
.referrer_policy(self.referrer_policy);
// Step 12. Return request.
diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs
index 66bcf2d91e0..617968b78f6 100644
--- a/components/script/dom/htmlscriptelement.rs
+++ b/components/script/dom/htmlscriptelement.rs
@@ -41,6 +41,7 @@ use crate::dom::attr::Attr;
use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use crate::dom::bindings::codegen::Bindings::HTMLScriptElementBinding::HTMLScriptElementMethods;
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
+use crate::dom::bindings::codegen::GenericBindings::HTMLElementBinding::HTMLElement_Binding::HTMLElementMethods;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::refcounted::Trusted;
use crate::dom::bindings::reflector::DomGlobal;
@@ -582,6 +583,7 @@ pub(crate) fn script_fetch_request(
.parser_metadata(options.parser_metadata)
.integrity_metadata(options.integrity_metadata.clone())
.referrer_policy(options.referrer_policy)
+ .cryptographic_nonce_metadata(options.cryptographic_nonce)
}
/// <https://html.spec.whatwg.org/multipage/#fetch-a-classic-script>
@@ -776,7 +778,7 @@ impl HTMLScriptElement {
// Step 29. Fetch options.
let options = ScriptFetchOptions {
- cryptographic_nonce: "".into(),
+ cryptographic_nonce: self.upcast::<HTMLElement>().Nonce().into(),
integrity_metadata: integrity_metadata.to_owned(),
parser_metadata,
referrer: self.global().get_referrer(),
diff --git a/components/script/dom/servoparser/prefetch.rs b/components/script/dom/servoparser/prefetch.rs
index 2d3c1569375..81a6f6ce5b1 100644
--- a/components/script/dom/servoparser/prefetch.rs
+++ b/components/script/dom/servoparser/prefetch.rs
@@ -109,6 +109,10 @@ impl TokenSink for PrefetchSink {
.get_attr(tag, local_name!("integrity"))
.map(|attr| String::from(&attr.value))
.unwrap_or_default();
+ let cryptographic_nonce = self
+ .get_attr(tag, local_name!("nonce"))
+ .map(|attr| String::from(&attr.value))
+ .unwrap_or_default();
let request = script_fetch_request(
self.webview_id,
url,
@@ -119,7 +123,7 @@ impl TokenSink for PrefetchSink {
referrer: self.referrer.clone(),
referrer_policy: self.referrer_policy,
integrity_metadata,
- cryptographic_nonce: String::new(),
+ cryptographic_nonce,
credentials_mode: CredentialsMode::CredentialsSameOrigin,
parser_metadata: ParserMetadata::ParserInserted,
},
diff --git a/components/script/dom/svgelement.rs b/components/script/dom/svgelement.rs
index 525c93c5741..6dd90a2efa8 100644
--- a/components/script/dom/svgelement.rs
+++ b/components/script/dom/svgelement.rs
@@ -5,6 +5,7 @@
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix, local_name, namespace_url, ns};
use js::rust::HandleObject;
+use script_bindings::str::DOMString;
use style_dom::ElementState;
use crate::dom::bindings::codegen::Bindings::SVGElementBinding::SVGElementMethods;
@@ -81,6 +82,14 @@ impl SVGElementMethods<crate::DomTypeHolder> for SVGElement {
})
}
+ // FIXME: The nonce should be stored in an internal slot instead of an
+ // attribute (https://html.spec.whatwg.org/multipage/#cryptographicnonce)
+ // https://html.spec.whatwg.org/multipage/#dom-noncedelement-nonce
+ make_getter!(Nonce, "nonce");
+
+ // https://html.spec.whatwg.org/multipage/#dom-noncedelement-nonce
+ make_setter!(SetNonce, "nonce");
+
// https://html.spec.whatwg.org/multipage/#dom-fe-autofocus
fn Autofocus(&self) -> bool {
self.element.has_attribute(&local_name!("autofocus"))
diff --git a/components/script/fetch.rs b/components/script/fetch.rs
index 1480e389b65..ca46eb6ae60 100644
--- a/components/script/fetch.rs
+++ b/components/script/fetch.rs
@@ -117,6 +117,7 @@ fn request_init_from_request(request: NetTraitsRequest) -> RequestBuilder {
target_webview_id: request.target_webview_id,
redirect_mode: request.redirect_mode,
integrity_metadata: request.integrity_metadata.clone(),
+ cryptographic_nonce_metadata: request.cryptographic_nonce_metadata.clone(),
url_list: vec![],
parser_metadata: request.parser_metadata,
initiator: request.initiator,