mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Implement PolicyContainer and update the default ReferrerPolicy (#33977)
* Implement PolicyContainer Signed-off-by: Shane Handley <shanehandley@fastmail.com> * implement small parts of fetch that interact with policy container Signed-off-by: Shane Handley <shanehandley@fastmail.com> * fix: allow policy container's csp list to be unset Signed-off-by: Shane Handley <shanehandley@fastmail.com> * fix: use the correct default policy when parsing from a token Signed-off-by: Shane Handley <shanehandley@fastmail.com> --------- Signed-off-by: Shane Handley <shanehandley@fastmail.com>
This commit is contained in:
parent
4f6283d7fe
commit
6451767428
201 changed files with 210 additions and 5178 deletions
|
@ -36,6 +36,7 @@ use metrics::{
|
|||
ProgressiveWebMetric,
|
||||
};
|
||||
use mime::{self, Mime};
|
||||
use net_traits::policy_container::PolicyContainer;
|
||||
use net_traits::pub_domains::is_pub_domain;
|
||||
use net_traits::request::RequestBuilder;
|
||||
use net_traits::response::HttpsState;
|
||||
|
@ -75,7 +76,7 @@ use crate::document_loader::{DocumentLoader, LoadType};
|
|||
use crate::dom::attr::Attr;
|
||||
use crate::dom::beforeunloadevent::BeforeUnloadEvent;
|
||||
use crate::dom::bindings::callback::ExceptionHandling;
|
||||
use crate::dom::bindings::cell::{ref_filter_map, DomRefCell, Ref, RefMut};
|
||||
use crate::dom::bindings::cell::{DomRefCell, Ref, RefMut};
|
||||
use crate::dom::bindings::codegen::Bindings::BeforeUnloadEventBinding::BeforeUnloadEvent_Binding::BeforeUnloadEventMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::DocumentBinding::{
|
||||
DocumentMethods, DocumentReadyState, DocumentVisibilityState, NamedPropertyValue,
|
||||
|
@ -377,6 +378,9 @@ pub struct Document {
|
|||
referrer: Option<String>,
|
||||
/// <https://html.spec.whatwg.org/multipage/#target-element>
|
||||
target_element: MutNullableDom<Element>,
|
||||
/// <https://html.spec.whatwg.org/multipage/#concept-document-policy-container>
|
||||
#[no_trace]
|
||||
policy_container: DomRefCell<PolicyContainer>,
|
||||
/// <https://w3c.github.io/uievents/#event-type-dblclick>
|
||||
#[ignore_malloc_size_of = "Defined in std"]
|
||||
#[no_trace]
|
||||
|
@ -446,10 +450,6 @@ pub struct Document {
|
|||
DomRefCell<HashMapTracedValues<WebGLContextId, Dom<WebGLRenderingContext>>>,
|
||||
/// List of all WebGPU context IDs that need flushing.
|
||||
dirty_webgpu_contexts: DomRefCell<HashMapTracedValues<WebGPUContextId, Dom<GPUCanvasContext>>>,
|
||||
/// <https://html.spec.whatwg.org/multipage/#concept-document-csp-list>
|
||||
#[ignore_malloc_size_of = "Defined in rust-content-security-policy"]
|
||||
#[no_trace]
|
||||
csp_list: DomRefCell<Option<CspList>>,
|
||||
/// <https://w3c.github.io/slection-api/#dfn-selection>
|
||||
selection: MutNullableDom<Selection>,
|
||||
/// A timeline for animations which is used for synchronizing animations.
|
||||
|
@ -2175,12 +2175,16 @@ impl Document {
|
|||
}
|
||||
}
|
||||
|
||||
/// Add the CSP list and HTTPS state to a given request.
|
||||
pub fn policy_container(&self) -> Ref<PolicyContainer> {
|
||||
self.policy_container.borrow()
|
||||
}
|
||||
|
||||
/// Add the policy container and HTTPS state to a given request.
|
||||
///
|
||||
/// TODO: Can this hapen for all requests that go through the document?
|
||||
pub(crate) fn prepare_request(&self, request: RequestBuilder) -> RequestBuilder {
|
||||
request
|
||||
.csp_list(self.get_csp_list().map(|list| list.clone()))
|
||||
.policy_container(self.policy_container().to_owned())
|
||||
.https_state(self.https_state.get())
|
||||
}
|
||||
|
||||
|
@ -3399,6 +3403,7 @@ impl Document {
|
|||
referrer,
|
||||
referrer_policy: Cell::new(referrer_policy),
|
||||
target_element: MutNullableDom::new(None),
|
||||
policy_container: DomRefCell::new(PolicyContainer::default()),
|
||||
last_click_info: DomRefCell::new(None),
|
||||
ignore_destructive_writes_counter: Default::default(),
|
||||
ignore_opens_during_unload_counter: Default::default(),
|
||||
|
@ -3424,7 +3429,6 @@ impl Document {
|
|||
media_controls: DomRefCell::new(HashMap::new()),
|
||||
dirty_webgl_contexts: DomRefCell::new(HashMapTracedValues::new()),
|
||||
dirty_webgpu_contexts: DomRefCell::new(HashMapTracedValues::new()),
|
||||
csp_list: DomRefCell::new(None),
|
||||
selection: MutNullableDom::new(None),
|
||||
animation_timeline: if pref!(layout.animations.test.enabled) {
|
||||
DomRefCell::new(AnimationTimeline::new_for_testing())
|
||||
|
@ -3495,11 +3499,11 @@ impl Document {
|
|||
}
|
||||
|
||||
pub fn set_csp_list(&self, csp_list: Option<CspList>) {
|
||||
*self.csp_list.borrow_mut() = csp_list;
|
||||
self.policy_container.borrow_mut().set_csp_list(csp_list);
|
||||
}
|
||||
|
||||
pub fn get_csp_list(&self) -> Option<Ref<CspList>> {
|
||||
ref_filter_map(self.csp_list.borrow(), Option::as_ref)
|
||||
pub fn get_csp_list(&self) -> Option<CspList> {
|
||||
self.policy_container.borrow().csp_list.clone()
|
||||
}
|
||||
|
||||
/// <https://www.w3.org/TR/CSP/#should-block-inline>
|
||||
|
@ -4273,6 +4277,7 @@ impl ProfilerMetadataFactory for Document {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
impl DocumentMethods for Document {
|
||||
// https://dom.spec.whatwg.org/#dom-document-document
|
||||
fn Constructor(
|
||||
|
@ -5619,11 +5624,11 @@ fn update_with_current_instant(marker: &Cell<Option<CrossProcessInstant>>) {
|
|||
pub fn determine_policy_for_token(token: &str) -> Option<ReferrerPolicy> {
|
||||
match_ignore_ascii_case! { token,
|
||||
"never" | "no-referrer" => Some(ReferrerPolicy::NoReferrer),
|
||||
"default" | "no-referrer-when-downgrade" => Some(ReferrerPolicy::NoReferrerWhenDowngrade),
|
||||
"no-referrer-when-downgrade" => Some(ReferrerPolicy::NoReferrerWhenDowngrade),
|
||||
"origin" => Some(ReferrerPolicy::Origin),
|
||||
"same-origin" => Some(ReferrerPolicy::SameOrigin),
|
||||
"strict-origin" => Some(ReferrerPolicy::StrictOrigin),
|
||||
"strict-origin-when-cross-origin" => Some(ReferrerPolicy::StrictOriginWhenCrossOrigin),
|
||||
"default" | "strict-origin-when-cross-origin" => Some(ReferrerPolicy::StrictOriginWhenCrossOrigin),
|
||||
"origin-when-cross-origin" => Some(ReferrerPolicy::OriginWhenCrossOrigin),
|
||||
"always" | "unsafe-url" => Some(ReferrerPolicy::UnsafeUrl),
|
||||
"" => Some(ReferrerPolicy::NoReferrer),
|
||||
|
|
|
@ -45,6 +45,7 @@ use net_traits::filemanager_thread::{
|
|||
FileManagerResult, FileManagerThreadMsg, ReadFileProgress, RelativePos,
|
||||
};
|
||||
use net_traits::image_cache::ImageCache;
|
||||
use net_traits::policy_container::PolicyContainer;
|
||||
use net_traits::request::{Referrer, RequestBuilder};
|
||||
use net_traits::response::HttpsState;
|
||||
use net_traits::{
|
||||
|
@ -2373,6 +2374,17 @@ impl GlobalScope {
|
|||
unreachable!();
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#concept-settings-object-policy-container>
|
||||
pub fn policy_container(&self) -> PolicyContainer {
|
||||
if let Some(window) = self.downcast::<Window>() {
|
||||
return window.Document().policy_container().to_owned();
|
||||
}
|
||||
if let Some(worker) = self.downcast::<WorkerGlobalScope>() {
|
||||
return worker.policy_container().to_owned();
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
/// Get the [base url](https://html.spec.whatwg.org/multipage/#api-base-url)
|
||||
/// for this global scope.
|
||||
pub fn api_base_url(&self) -> ServoUrl {
|
||||
|
@ -3116,8 +3128,8 @@ impl GlobalScope {
|
|||
|
||||
/// <https://www.w3.org/TR/CSP/#get-csp-of-object>
|
||||
pub fn get_csp_list(&self) -> Option<CspList> {
|
||||
if let Some(window) = self.downcast::<Window>() {
|
||||
return window.Document().get_csp_list().map(|c| c.clone());
|
||||
if self.downcast::<Window>().is_some() {
|
||||
return self.policy_container().csp_list;
|
||||
}
|
||||
// TODO: Worker and Worklet global scopes.
|
||||
None
|
||||
|
|
|
@ -95,7 +95,7 @@ impl HTMLHeadElement {
|
|||
|
||||
let mut csp_list: Option<CspList> = None;
|
||||
let node = self.upcast::<Node>();
|
||||
let candinates = node
|
||||
let candidates = node
|
||||
.traverse_preorder(ShadowIncluding::No)
|
||||
.filter_map(DomRoot::downcast::<Element>)
|
||||
.filter(|elem| elem.is::<HTMLMetaElement>())
|
||||
|
@ -109,7 +109,7 @@ impl HTMLHeadElement {
|
|||
.is_some()
|
||||
});
|
||||
|
||||
for meta in candinates {
|
||||
for meta in candidates {
|
||||
if let Some(ref content) = meta.get_attribute(&ns!(), &local_name!("content")) {
|
||||
let content = content.value();
|
||||
let content_val = content.trim();
|
||||
|
|
|
@ -11,6 +11,7 @@ use dom_struct::dom_struct;
|
|||
use embedder_traits::EmbedderMsg;
|
||||
use html5ever::{local_name, namespace_url, ns, LocalName, Prefix};
|
||||
use js::rust::HandleObject;
|
||||
use net_traits::policy_container::PolicyContainer;
|
||||
use net_traits::request::{
|
||||
CorsSettings, Destination, Initiator, Referrer, RequestBuilder, RequestId,
|
||||
};
|
||||
|
@ -76,6 +77,7 @@ struct LinkProcessingOptions {
|
|||
link_type: String,
|
||||
cross_origin: Option<CorsSettings>,
|
||||
referrer_policy: Option<ReferrerPolicy>,
|
||||
policy_container: PolicyContainer,
|
||||
source_set: Option<()>,
|
||||
base_url: ServoUrl,
|
||||
// Some fields that we don't need yet are missing
|
||||
|
@ -322,6 +324,7 @@ impl HTMLLinkElement {
|
|||
link_type: String::new(),
|
||||
cross_origin: cors_setting_for_element(element),
|
||||
referrer_policy: referrer_policy_for_element(element),
|
||||
policy_container: document.policy_container().to_owned(),
|
||||
source_set: None, // FIXME
|
||||
base_url: document.borrow().base_url(),
|
||||
};
|
||||
|
@ -642,7 +645,7 @@ impl LinkProcessingOptions {
|
|||
|
||||
// Step 5. Let request be the result of creating a potential-CORS request given
|
||||
// url, options's destination, and options's crossorigin.
|
||||
// FIXME: Step 6. Set request's policy container to options's policy container.
|
||||
// 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 9. Set request's referrer policy to options's referrer policy.
|
||||
|
@ -657,6 +660,7 @@ impl LinkProcessingOptions {
|
|||
Referrer::NoReferrer,
|
||||
)
|
||||
.integrity_metadata(self.integrity)
|
||||
.policy_container(self.policy_container)
|
||||
.referrer_policy(self.referrer_policy);
|
||||
|
||||
// Step 12. Return request.
|
||||
|
|
|
@ -7,6 +7,7 @@ use std::cell::Cell;
|
|||
use base::id::ServiceWorkerRegistrationId;
|
||||
use devtools_traits::WorkerId;
|
||||
use dom_struct::dom_struct;
|
||||
use net_traits::request::Referrer;
|
||||
use script_traits::{ScopeThings, WorkerScriptLoadOrigin};
|
||||
use servo_url::ServoUrl;
|
||||
use uuid::Uuid;
|
||||
|
@ -112,8 +113,12 @@ impl ServiceWorkerRegistration {
|
|||
|
||||
pub fn create_scope_things(global: &GlobalScope, script_url: ServoUrl) -> ScopeThings {
|
||||
let worker_load_origin = WorkerScriptLoadOrigin {
|
||||
referrer_url: None,
|
||||
referrer_policy: None,
|
||||
referrer_url: match global.get_referrer() {
|
||||
Referrer::Client(url) => Some(url),
|
||||
Referrer::ReferrerUrl(url) => Some(url),
|
||||
_ => None,
|
||||
},
|
||||
referrer_policy: Some(global.policy_container().referrer_policy),
|
||||
pipeline_id: global.pipeline_id(),
|
||||
};
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ use ipc_channel::ipc::IpcSender;
|
|||
use js::jsval::UndefinedValue;
|
||||
use js::panic::maybe_resume_unwind;
|
||||
use js::rust::{HandleValue, MutableHandleValue, ParentRuntime};
|
||||
use net_traits::policy_container::PolicyContainer;
|
||||
use net_traits::request::{
|
||||
CredentialsMode, Destination, ParserMetadata, RequestBuilder as NetRequestInit,
|
||||
};
|
||||
|
@ -109,6 +110,9 @@ pub struct WorkerGlobalScope {
|
|||
runtime: DomRefCell<Option<Runtime>>,
|
||||
location: MutNullableDom<WorkerLocation>,
|
||||
navigator: MutNullableDom<WorkerNavigator>,
|
||||
#[no_trace]
|
||||
/// <https://html.spec.whatwg.org/multipage/#the-workerglobalscope-common-interface:policy-container>
|
||||
policy_container: DomRefCell<PolicyContainer>,
|
||||
|
||||
#[ignore_malloc_size_of = "Defined in ipc-channel"]
|
||||
#[no_trace]
|
||||
|
@ -171,6 +175,7 @@ impl WorkerGlobalScope {
|
|||
runtime: DomRefCell::new(Some(runtime)),
|
||||
location: Default::default(),
|
||||
navigator: Default::default(),
|
||||
policy_container: Default::default(),
|
||||
devtools_receiver,
|
||||
_devtools_sender: init.from_devtools_sender,
|
||||
navigation_start: CrossProcessInstant::now(),
|
||||
|
@ -230,6 +235,10 @@ impl WorkerGlobalScope {
|
|||
pub fn pipeline_id(&self) -> PipelineId {
|
||||
self.globalscope.pipeline_id()
|
||||
}
|
||||
|
||||
pub fn policy_container(&self) -> Ref<PolicyContainer> {
|
||||
self.policy_container.borrow()
|
||||
}
|
||||
}
|
||||
|
||||
impl WorkerGlobalScopeMethods for WorkerGlobalScope {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue