diff options
author | Tim van der Lippe <TimvdLippe@users.noreply.github.com> | 2025-05-11 17:38:13 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-11 15:38:13 +0000 |
commit | 4821bc0ab01e1ed0bb27e86c2df545019bd3856a (patch) | |
tree | 4598dd280371ac29b9818a6888f5d28b19e9ced2 /components/script | |
parent | dc0e7587bf965047358254be1da5efa41079ee96 (diff) | |
download | servo-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.rs | 4 | ||||
-rw-r--r-- | components/script/dom/element.rs | 29 |
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, |