mirror of
https://github.com/servo/servo
synced 2026-04-26 17:45:19 +02:00
Fix CSP nonce validation and violation reporting for external scripts (#40956)
This PR fixes two related issues with Content Security Policy (CSP)
nonce validation for external scripts:
1. Missing nonce validation for external scripts with malformed
attributes
2. Incorrect violation event reporting for blocked external resources
This makes servo closer to passing the `nonce-enforce-blocked` wpt test.
The remaining failures are blocked by required changes in the html
parser.
1. Svg script support (https://github.com/servo/html5ever/issues/118)
```html
<svg xmlns="http://www.w3.org/2000/svg">
<script attribute attribute nonce="abc">
t.unreached_func("Duplicate attribute in SVG, no execution.")();
</script>
</svg>
```
2. Duplicate attrs check
the html parser needs to provide this flag, as mentioned on the original
commit message
(4821bc0ab0)
```html
<script attribute attribute nonce="abc">
t.unreached_func("Duplicate attribute, no execution.")();
</script>
<script attribute attribute=<style nonce="abc">
t.unreached_func("2# Duplicate attribute, no execution.")();
</script>
[...]
<script src="../support/nonce-should-be-blocked.js?5" attribute attribute nonce="abc"></script>
```
I've also created a PR to implement the duplicate attrs flag on
html5ever https://github.com/servo/html5ever/pull/695
Testing: doesn't fixes the aforementioned wpt test yet.
Fixes: part of #36437
---------
Signed-off-by: Dyego Aurélio <dyegoaurelio@gmail.com>
This commit is contained in:
@@ -472,10 +472,7 @@ impl FetchResponseListener for ClassicContext {
|
||||
fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<Violation>) {
|
||||
let global = &self.resource_timing_global();
|
||||
let elem = self.elem.root();
|
||||
let source_position = elem
|
||||
.upcast::<Element>()
|
||||
.compute_source_position(elem.line_number as u32);
|
||||
global.report_csp_violations(violations, Some(elem.upcast()), Some(source_position));
|
||||
global.report_csp_violations(violations, Some(elem.upcast()), None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -725,7 +722,15 @@ impl HTMLScriptElement {
|
||||
};
|
||||
|
||||
// Step 24. Let cryptographic nonce be el's [[CryptographicNonce]] internal slot's value.
|
||||
let cryptographic_nonce = self.upcast::<Element>().nonce_value();
|
||||
// If the element has a nonce content attribute but is not nonceable strip the nonce to prevent injection attacks.
|
||||
// Elements without a nonce content attribute (e.g. JS-created with .nonce = "abc")
|
||||
// use the internal slot directly — the nonceable check only applies to parser-created elements.
|
||||
let el = self.upcast::<Element>();
|
||||
let cryptographic_nonce = if el.is_nonceable() || !el.has_attribute(&local_name!("nonce")) {
|
||||
el.nonce_value().trim().to_owned()
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
// Step 25. If el has an integrity attribute, then let integrity metadata be that attribute's value.
|
||||
// Otherwise, let integrity metadata be the empty string.
|
||||
|
||||
Reference in New Issue
Block a user