aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/document.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/document.rs')
-rw-r--r--components/script/dom/document.rs40
1 files changed, 38 insertions, 2 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 452212a2b3c..6581dbd54bb 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -110,6 +110,7 @@ use crate::task::TaskBox;
use crate::task_source::{TaskSource, TaskSourceName};
use crate::timers::OneshotTimerCallback;
use canvas_traits::webgl::{self, WebGLContextId, WebGLMsg};
+use content_security_policy::{self as csp, CspList};
use cookie::Cookie;
use devtools_traits::ScriptToDevtoolsControlMsg;
use dom_struct::dom_struct;
@@ -137,6 +138,7 @@ use num_traits::ToPrimitive;
use percent_encoding::percent_decode;
use profile_traits::ipc as profile_ipc;
use profile_traits::time::{TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType};
+use ref_filter_map::ref_filter_map;
use ref_slice::ref_slice;
use script_layout_interface::message::{Msg, ReflowGoal};
use script_traits::{AnimationState, DocumentActivity, MouseButton, MouseEventType};
@@ -148,7 +150,7 @@ use servo_atoms::Atom;
use servo_config::pref;
use servo_media::{ClientContextId, ServoMedia};
use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl};
-use std::borrow::ToOwned;
+use std::borrow::Cow;
use std::cell::{Cell, Ref, RefMut};
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::{HashMap, HashSet, VecDeque};
@@ -398,6 +400,9 @@ pub struct Document {
media_controls: DomRefCell<HashMap<String, Dom<ShadowRoot>>>,
/// List of all WebGL context IDs that need flushing.
dirty_webgl_contexts: DomRefCell<HashSet<WebGLContextId>>,
+ /// https://html.spec.whatwg.org/multipage/#concept-document-csp-list
+ #[ignore_malloc_size_of = "Defined in rust-content-security-policy"]
+ csp_list: DomRefCell<Option<CspList>>,
}
#[derive(JSTraceable, MallocSizeOf)]
@@ -1734,9 +1739,10 @@ impl Document {
pub fn fetch_async(
&self,
load: LoadType,
- request: RequestBuilder,
+ mut request: RequestBuilder,
fetch_target: IpcSender<FetchResponseMsg>,
) {
+ request.csp_list = self.get_csp_list().map(|x| x.clone());
let mut loader = self.loader.borrow_mut();
loader.fetch_async(load, request, fetch_target);
}
@@ -2806,9 +2812,39 @@ impl Document {
shadow_roots_styles_changed: Cell::new(false),
media_controls: DomRefCell::new(HashMap::new()),
dirty_webgl_contexts: DomRefCell::new(HashSet::new()),
+ csp_list: DomRefCell::new(None),
}
}
+ pub fn set_csp_list(&self, csp_list: Option<CspList>) {
+ *self.csp_list.borrow_mut() = csp_list;
+ }
+
+ pub fn get_csp_list(&self) -> Option<Ref<CspList>> {
+ ref_filter_map(self.csp_list.borrow(), Option::as_ref)
+ }
+
+ /// https://www.w3.org/TR/CSP/#should-block-inline
+ pub fn should_elements_inline_type_behavior_be_blocked(
+ &self,
+ el: &Element,
+ type_: csp::InlineCheckType,
+ source: &str,
+ ) -> csp::CheckResult {
+ let element = csp::Element {
+ nonce: el
+ .get_attribute(&ns!(), &local_name!("nonce"))
+ .map(|attr| Cow::Owned(attr.value().to_string())),
+ };
+ // TODO: Instead of ignoring violations, report them.
+ self.get_csp_list()
+ .map(|c| {
+ c.should_elements_inline_type_behavior_be_blocked(&element, type_, source)
+ .0
+ })
+ .unwrap_or(csp::CheckResult::Allowed)
+ }
+
/// Prevent any JS or layout from running until the corresponding call to
/// `remove_script_and_layout_blocker`. Used to isolate periods in which
/// the DOM is in an unstable state and should not be exposed to arbitrary