aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorTim van der Lippe <TimvdLippe@users.noreply.github.com>2025-05-11 17:38:13 +0200
committerGitHub <noreply@github.com>2025-05-11 15:38:13 +0000
commit4821bc0ab01e1ed0bb27e86c2df545019bd3856a (patch)
tree4598dd280371ac29b9818a6888f5d28b19e9ced2 /components/script
parentdc0e7587bf965047358254be1da5efa41079ee96 (diff)
downloadservo-4821bc0ab01e1ed0bb27e86c2df545019bd3856a.tar.gz
servo-4821bc0ab01e1ed0bb27e86c2df545019bd3856a.zip
Implement is-element-nonceable (#36961)
Unfortunately while it now passes almost all cases in `tests/wpt/tests/content-security-policy/script-src/nonce-enforce-blocked.html`, the test in question doesn't pass yet as it requires all cases to be correct. Here, we still miss the "check for duplicate attributes during parsing". Since we don't have this information available yet from the parser, skip this for now. Part of #36437 Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/document.rs4
-rw-r--r--components/script/dom/element.rs29
2 files changed, 30 insertions, 3 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 0c71f526a0e..ad95b9b9a94 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -4313,9 +4313,7 @@ impl Document {
},
Some(csp_list) => {
let element = csp::Element {
- nonce: el
- .get_attribute(&ns!(), &local_name!("nonce"))
- .map(|attr| Cow::Owned(attr.value().to_string())),
+ nonce: el.nonce_attribute_if_nonceable().map(Cow::Owned),
};
csp_list.should_elements_inline_type_behavior_be_blocked(&element, type_, source)
},
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 7770d0c8fa5..5c79dbc0a5b 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -125,6 +125,7 @@ use crate::dom::htmllinkelement::HTMLLinkElement;
use crate::dom::htmlobjectelement::HTMLObjectElement;
use crate::dom::htmloptgroupelement::HTMLOptGroupElement;
use crate::dom::htmloutputelement::HTMLOutputElement;
+use crate::dom::htmlscriptelement::HTMLScriptElement;
use crate::dom::htmlselectelement::HTMLSelectElement;
use crate::dom::htmlslotelement::{HTMLSlotElement, Slottable};
use crate::dom::htmlstyleelement::HTMLStyleElement;
@@ -2174,6 +2175,34 @@ impl Element {
};
}
+ /// <https://www.w3.org/TR/CSP/#is-element-nonceable>
+ pub(crate) fn nonce_attribute_if_nonceable(&self) -> Option<String> {
+ // Step 1: If element does not have an attribute named "nonce", return "Not Nonceable".
+ let nonce_attribute = self.get_attribute(&ns!(), &local_name!("nonce"))?;
+ // Step 2: If element is a script element, then for each attribute of element’s attribute list:
+ if self.downcast::<HTMLScriptElement>().is_some() {
+ for attr in self.attrs().iter() {
+ // Step 2.1: If attribute’s name contains an ASCII case-insensitive match
+ // for "<script" or "<style", return "Not Nonceable".
+ let attr_name = attr.name().to_ascii_lowercase();
+ if attr_name.contains("<script") || attr_name.contains("<style") {
+ return None;
+ }
+ // Step 2.2: If attribute’s value contains an ASCII case-insensitive match
+ // for "<script" or "<style", return "Not Nonceable".
+ let attr_value = attr.value().to_ascii_lowercase();
+ if attr_value.contains("<script") || attr_value.contains("<style") {
+ return None;
+ }
+ }
+ }
+ // Step 3: If element had a duplicate-attribute parse error during tokenization, return "Not Nonceable".
+ // TODO(https://github.com/servo/servo/issues/4577 and https://github.com/whatwg/html/issues/3257):
+ // Figure out how to retrieve this information from the parser
+ // Step 4: Return "Nonceable".
+ Some(nonce_attribute.value().to_string().trim().to_owned())
+ }
+
// https://dom.spec.whatwg.org/#insert-adjacent
pub(crate) fn insert_adjacent(
&self,