diff options
Diffstat (limited to 'components')
-rw-r--r-- | components/constellation/browsingcontext.rs | 8 | ||||
-rw-r--r-- | components/constellation/constellation.rs | 18 | ||||
-rw-r--r-- | components/constellation/pipeline.rs | 1 | ||||
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 13 | ||||
-rw-r--r-- | components/script/dom/bindings/guard.rs | 12 | ||||
-rw-r--r-- | components/script/dom/dissimilaroriginwindow.rs | 2 | ||||
-rw-r--r-- | components/script/dom/globalscope.rs | 28 | ||||
-rw-r--r-- | components/script/dom/htmlanchorelement.rs | 2 | ||||
-rw-r--r-- | components/script/dom/htmlformelement.rs | 1 | ||||
-rw-r--r-- | components/script/dom/htmliframeelement.rs | 4 | ||||
-rw-r--r-- | components/script/dom/location.rs | 1 | ||||
-rw-r--r-- | components/script/dom/webidls/WindowOrWorkerGlobalScope.webidl | 5 | ||||
-rw-r--r-- | components/script/dom/window.rs | 8 | ||||
-rw-r--r-- | components/script/dom/windowproxy.rs | 3 | ||||
-rw-r--r-- | components/script/dom/workerglobalscope.rs | 9 | ||||
-rw-r--r-- | components/script/dom/workletglobalscope.rs | 4 | ||||
-rw-r--r-- | components/script/script_thread.rs | 14 | ||||
-rw-r--r-- | components/script_traits/lib.rs | 12 | ||||
-rw-r--r-- | components/webdriver_server/lib.rs | 9 |
19 files changed, 145 insertions, 9 deletions
diff --git a/components/constellation/browsingcontext.rs b/components/constellation/browsingcontext.rs index d90cb79cadd..4f15638fcff 100644 --- a/components/constellation/browsingcontext.rs +++ b/components/constellation/browsingcontext.rs @@ -24,6 +24,9 @@ pub struct NewBrowsingContextInfo { /// Whether this browsing context is in private browsing mode. pub is_private: bool, + /// Whether this browsing context inherits a secure context. + pub inherited_secure_context: Option<bool>, + /// Whether this browsing context should be treated as visible for the /// purposes of scheduling and resource management. pub is_visible: bool, @@ -51,6 +54,9 @@ pub struct BrowsingContext { /// Whether this browsing context is in private browsing mode. pub is_private: bool, + /// Whether this browsing context inherits a secure context. + pub inherited_secure_context: Option<bool>, + /// Whether this browsing context should be treated as visible for the /// purposes of scheduling and resource management. pub is_visible: bool, @@ -78,6 +84,7 @@ impl BrowsingContext { parent_pipeline_id: Option<PipelineId>, size: Size2D<f32, CSSPixel>, is_private: bool, + inherited_secure_context: Option<bool>, is_visible: bool, ) -> BrowsingContext { let mut pipelines = HashSet::new(); @@ -88,6 +95,7 @@ impl BrowsingContext { top_level_id, size, is_private, + inherited_secure_context, is_visible, pipeline_id, parent_pipeline_id, diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index e01dc7e76ef..6fbd449a236 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -1249,6 +1249,7 @@ where parent_pipeline_id: Option<PipelineId>, size: Size2D<f32, CSSPixel>, is_private: bool, + inherited_secure_context: Option<bool>, is_visible: bool, ) { debug!("Creating new browsing context {}", browsing_context_id); @@ -1283,6 +1284,7 @@ where parent_pipeline_id, size, is_private, + inherited_secure_context, is_visible, ); self.browsing_contexts @@ -1541,6 +1543,7 @@ where None, Referrer::NoReferrer, None, + None, ); let ctx_id = BrowsingContextId::from(top_level_browsing_context_id); let pipeline_id = match self.browsing_contexts.get(&ctx_id) { @@ -2911,6 +2914,7 @@ where None, Referrer::NoReferrer, None, + None, ); let sandbox = IFrameSandboxState::IFrameSandboxed; let is_private = false; @@ -3027,6 +3031,7 @@ where None, Referrer::NoReferrer, None, + None, ); let sandbox = IFrameSandboxState::IFrameUnsandboxed; let is_private = false; @@ -3071,6 +3076,7 @@ where new_browsing_context_info: Some(NewBrowsingContextInfo { parent_pipeline_id: None, is_private: is_private, + inherited_secure_context: None, is_visible: is_visible, }), window_size, @@ -3178,6 +3184,7 @@ where new_pipeline_id, is_private, mut replace, + .. } = load_info.info; // If no url is specified, reload. @@ -3293,9 +3300,9 @@ where Some(pipeline) => (pipeline.event_loop.clone(), pipeline.browsing_context_id), None => return warn!("Script loaded url in closed iframe {}.", parent_pipeline_id), }; - let (is_parent_private, is_parent_visible) = + let (is_parent_private, is_parent_visible, is_parent_secure) = match self.browsing_contexts.get(&parent_browsing_context_id) { - Some(ctx) => (ctx.is_private, ctx.is_visible), + Some(ctx) => (ctx.is_private, ctx.is_visible, ctx.inherited_secure_context), None => { return warn!( "New iframe {} loaded in closed parent browsing context {}.", @@ -3327,6 +3334,7 @@ where new_browsing_context_info: Some(NewBrowsingContextInfo { parent_pipeline_id: Some(parent_pipeline_id), is_private: is_private, + inherited_secure_context: is_parent_secure, is_visible: is_parent_visible, }), window_size: load_info.window_size.initial_viewport, @@ -3356,9 +3364,9 @@ where ); }, }; - let (is_opener_private, is_opener_visible) = + let (is_opener_private, is_opener_visible, is_opener_secure) = match self.browsing_contexts.get(&opener_browsing_context_id) { - Some(ctx) => (ctx.is_private, ctx.is_visible), + Some(ctx) => (ctx.is_private, ctx.is_visible, ctx.inherited_secure_context), None => { return warn!( "New auxiliary {} loaded in closed opener browsing context {}.", @@ -3416,6 +3424,7 @@ where // Auxiliary browsing contexts are always top-level. parent_pipeline_id: None, is_private: is_opener_private, + inherited_secure_context: is_opener_secure, is_visible: is_opener_visible, }), window_size: self.window_size.initial_viewport, @@ -4747,6 +4756,7 @@ where new_context_info.parent_pipeline_id, change.window_size, new_context_info.is_private, + new_context_info.inherited_secure_context, new_context_info.is_visible, ); self.update_activity(change.new_pipeline_id); diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs index 108bc403e42..c368b57f2a1 100644 --- a/components/constellation/pipeline.rs +++ b/components/constellation/pipeline.rs @@ -573,6 +573,7 @@ impl UnprivilegedPipelineContent { layout_is_busy: layout_thread_busy_flag.clone(), player_context: self.player_context.clone(), event_loop_waker, + inherited_secure_context: self.load_data.inherited_secure_context.clone(), }, self.load_data.clone(), self.opts.profile_script_events, diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 83e68cdce76..13c295ef1a2 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -1517,7 +1517,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider): returnType) -def MemberCondition(pref, func, exposed): +def MemberCondition(pref, func, exposed, secure): """ A string representing the condition for a member to actually be exposed. Any of the arguments can be None. If not None, they should have the @@ -1526,11 +1526,14 @@ def MemberCondition(pref, func, exposed): pref: The name of the preference. func: The name of the function. exposed: One or more names of an exposed global. + secure: Requires secure context. """ assert pref is None or isinstance(pref, str) assert func is None or isinstance(func, str) assert exposed is None or isinstance(exposed, set) - assert func is None or pref is None or exposed is None + assert func is None or pref is None or exposed is None or secure is None + if secure: + return 'Condition::SecureContext()' if pref: return 'Condition::Pref("%s")' % pref if func: @@ -1580,7 +1583,8 @@ class PropertyDefiner: "Pref"), PropertyDefiner.getStringAttr(interfaceMember, "Func"), - interfaceMember.exposureSet) + interfaceMember.exposureSet, + interfaceMember.getExtendedAttribute("SecureContext")) def generateGuardedArray(self, array, name, specTemplate, specTerminator, specType, getCondition, getDataTuple): @@ -3038,7 +3042,7 @@ let global = incumbent_global.reflector().get_jsobject();\n""" for m in interface.members: if m.isAttr() and not m.isStatic() and m.type.isJSONType(): name = m.identifier.name - conditions = MemberCondition(None, None, m.exposureSet) + conditions = MemberCondition(None, None, m.exposureSet, None) ret_conditions = '&[' + ", ".join(conditions) + "]" ret += fill( """ @@ -7838,6 +7842,7 @@ impl %(base)s { if PropertyDefiner.getStringAttr(m, 'Pref') or \ PropertyDefiner.getStringAttr(m, 'Func') or \ PropertyDefiner.getStringAttr(m, 'Exposed') or \ + m.getExtendedAttribute('SecureContext') or \ (m.isMethod() and m.isIdentifierLess()): continue display = m.identifier.name + ('()' if m.isMethod() else '') diff --git a/components/script/dom/bindings/guard.rs b/components/script/dom/bindings/guard.rs index 188d36fee17..17f3a3d20bc 100644 --- a/components/script/dom/bindings/guard.rs +++ b/components/script/dom/bindings/guard.rs @@ -6,6 +6,9 @@ use crate::dom::bindings::codegen::InterfaceObjectMap; use crate::dom::bindings::interface::is_exposed_in; +use crate::dom::globalscope::GlobalScope; +use crate::realms::AlreadyInRealm; +use crate::realms::InRealm; use crate::script_runtime::JSContext; use js::rust::HandleObject; use servo_config::prefs; @@ -45,16 +48,25 @@ pub enum Condition { Pref(&'static str), // The condition is satisfied if the interface is exposed in the global. Exposed(InterfaceObjectMap::Globals), + SecureContext(), /// The condition is always satisfied. Satisfied, } +fn is_secure_context(cx: JSContext) -> bool { + unsafe { + let in_realm_proof = AlreadyInRealm::assert_for_cx(JSContext::from_ptr(*cx)); + GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof)).is_secure_context() + } +} + impl Condition { pub fn is_satisfied(&self, cx: JSContext, obj: HandleObject, global: HandleObject) -> bool { match *self { Condition::Pref(name) => prefs::pref_map().get(name).as_bool().unwrap_or(false), Condition::Func(f) => f(cx, obj), Condition::Exposed(globals) => is_exposed_in(global, globals), + Condition::SecureContext() => is_secure_context(cx), Condition::Satisfied => true, } } diff --git a/components/script/dom/dissimilaroriginwindow.rs b/components/script/dom/dissimilaroriginwindow.rs index c00b08effe6..989aec3ff3d 100644 --- a/components/script/dom/dissimilaroriginwindow.rs +++ b/components/script/dom/dissimilaroriginwindow.rs @@ -57,12 +57,14 @@ impl DissimilarOriginWindow { global_to_clone_from.scheduler_chan().clone(), global_to_clone_from.resource_threads().clone(), global_to_clone_from.origin().clone(), + global_to_clone_from.creation_url().clone(), // FIXME(nox): The microtask queue is probably not important // here, but this whole DOM interface is a hack anyway. global_to_clone_from.microtask_queue().clone(), global_to_clone_from.is_headless(), global_to_clone_from.get_user_agent(), global_to_clone_from.wgpu_id_hub(), + Some(global_to_clone_from.is_secure_context()), ), window_proxy: Dom::from_ref(window_proxy), location: Default::default(), diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 56adc2b8d90..6e576c036f7 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -246,6 +246,9 @@ pub struct GlobalScope { /// The origin of the globalscope origin: MutableOrigin, + /// https://html.spec.whatwg.org/multipage/#concept-environment-creation-url + creation_url: Option<ServoUrl>, + /// A map for storing the previous permission state read results. permission_state_invocation_results: DomRefCell<HashMap<String, PermissionState>>, @@ -309,6 +312,9 @@ pub struct GlobalScope { /// List of ongoing dynamic module imports. dynamic_modules: DomRefCell<DynamicModuleList>, + + /// Is considered in a secure context + inherited_secure_context: Option<bool>, } /// A wrapper for glue-code between the ipc router and the event-loop. @@ -719,10 +725,12 @@ impl GlobalScope { scheduler_chan: IpcSender<TimerSchedulerMsg>, resource_threads: ResourceThreads, origin: MutableOrigin, + creation_url: Option<ServoUrl>, microtask_queue: Rc<MicrotaskQueue>, is_headless: bool, user_agent: Cow<'static, str>, gpu_id_hub: Arc<Mutex<Identities>>, + inherited_secure_context: Option<bool>, ) -> Self { Self { message_port_state: DomRefCell::new(MessagePortState::UnManaged), @@ -747,6 +755,7 @@ impl GlobalScope { timers: OneshotTimers::new(scheduler_chan), init_timers: Default::default(), origin, + creation_url, permission_state_invocation_results: Default::default(), microtask_queue, list_auto_close_worker: Default::default(), @@ -761,6 +770,7 @@ impl GlobalScope { https_state: Cell::new(HttpsState::None), console_group_stack: DomRefCell::new(Vec::new()), dynamic_modules: DomRefCell::new(DynamicModuleList::new()), + inherited_secure_context, } } @@ -2311,6 +2321,11 @@ impl GlobalScope { &self.origin } + /// Get the creation_url for this global scope + pub fn creation_url(&self) -> &Option<ServoUrl> { + &self.creation_url + } + pub fn image_cache(&self) -> Arc<dyn ImageCache> { if let Some(window) = self.downcast::<Window>() { return window.image_cache(); @@ -2994,6 +3009,19 @@ impl GlobalScope { self.https_state.set(https_state); } + pub fn is_secure_context(&self) -> bool { + if Some(false) == self.inherited_secure_context { + return false; + } + if let Some(creation_url) = self.creation_url() { + if creation_url.scheme() == "blob" && Some(true) == self.inherited_secure_context { + return true; + } + return creation_url.is_potentially_trustworthy(); + } + false + } + /// 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>() { diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index be246203121..e6583329880 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -703,12 +703,14 @@ pub fn follow_hyperlink(subject: &Element, hyperlink_suffix: Option<String>) { // Step 14 let pipeline_id = target_window.upcast::<GlobalScope>().pipeline_id(); + let secure = target_window.upcast::<GlobalScope>().is_secure_context(); let load_data = LoadData::new( LoadOrigin::Script(document.origin().immutable().clone()), url, Some(pipeline_id), referrer, referrer_policy, + Some(secure), ); let target = Trusted::new(target_window); let task = task!(navigate_follow_hyperlink: move || { diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index a4df1059a0c..d06fd85a426 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -811,6 +811,7 @@ impl HTMLFormElement { None, target_window.upcast::<GlobalScope>().get_referrer(), target_document.get_referrer_policy(), + Some(target_window.upcast::<GlobalScope>().is_secure_context()), ); // Step 22 diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 345e815ee50..6f5264999be 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -170,6 +170,7 @@ impl HTMLIFrameElement { top_level_browsing_context_id: top_level_browsing_context_id, new_pipeline_id: new_pipeline_id, is_private: false, // FIXME + inherited_secure_context: load_data.inherited_secure_context, replace: replace, }; @@ -244,6 +245,7 @@ impl HTMLIFrameElement { pipeline_id, window.upcast::<GlobalScope>().get_referrer(), document.get_referrer_policy(), + Some(window.upcast::<GlobalScope>().is_secure_context()), ); let element = self.upcast::<Element>(); load_data.srcdoc = String::from(element.get_string_attribute(&local_name!("srcdoc"))); @@ -327,6 +329,7 @@ impl HTMLIFrameElement { creator_pipeline_id, window.upcast::<GlobalScope>().get_referrer(), document.get_referrer_policy(), + Some(window.upcast::<GlobalScope>().is_secure_context()), ); let pipeline_id = self.pipeline_id(); @@ -354,6 +357,7 @@ impl HTMLIFrameElement { pipeline_id, window.upcast::<GlobalScope>().get_referrer(), document.get_referrer_policy(), + Some(window.upcast::<GlobalScope>().is_secure_context()), ); let browsing_context_id = BrowsingContextId::new(); let top_level_browsing_context_id = window.window_proxy().top_level_browsing_context_id(); diff --git a/components/script/dom/location.rs b/components/script/dom/location.rs index 48e8ea0c744..42e3a5846f3 100644 --- a/components/script/dom/location.rs +++ b/components/script/dom/location.rs @@ -52,6 +52,7 @@ impl Location { Some(pipeline_id), referrer, referrer_policy, + None, // Top navigation doesn't inherit secure context ); // TODO: rethrow exceptions, set exceptions enabled flag. self.window diff --git a/components/script/dom/webidls/WindowOrWorkerGlobalScope.webidl b/components/script/dom/webidls/WindowOrWorkerGlobalScope.webidl index 97b36721f8b..2ab8ba2c25d 100644 --- a/components/script/dom/webidls/WindowOrWorkerGlobalScope.webidl +++ b/components/script/dom/webidls/WindowOrWorkerGlobalScope.webidl @@ -36,5 +36,10 @@ partial interface mixin WindowOrWorkerGlobalScope { readonly attribute Performance performance; }; +// https://w3c.github.io/webappsec-secure-contexts/#monkey-patching-global-object +partial interface mixin WindowOrWorkerGlobalScope { + readonly attribute boolean isSecureContext; +}; + Window includes WindowOrWorkerGlobalScope; WorkerGlobalScope includes WindowOrWorkerGlobalScope; diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 09497c0798a..70734efb9bb 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -1381,6 +1381,10 @@ impl WindowMethods for Window { } rval.get() } + + fn IsSecureContext(&self) -> bool { + self.upcast::<GlobalScope>().is_secure_context() + } } impl Window { @@ -2357,6 +2361,7 @@ impl Window { parent_info: Option<PipelineId>, window_size: WindowSizeData, origin: MutableOrigin, + creator_url: ServoUrl, navigation_start: u64, navigation_start_precise: u64, webgl_chan: Option<WebGLChan>, @@ -2376,6 +2381,7 @@ impl Window { player_context: WindowGLContext, event_loop_waker: Option<Box<dyn EventLoopWaker>>, gpu_id_hub: Arc<ParkMutex<Identities>>, + inherited_secure_context: Option<bool>, ) -> DomRoot<Self> { let layout_rpc: Box<dyn LayoutRPC + Send> = { let (rpc_send, rpc_recv) = unbounded(); @@ -2396,10 +2402,12 @@ impl Window { scheduler_chan, resource_threads, origin, + Some(creator_url), microtask_queue, is_headless, user_agent, gpu_id_hub, + inherited_secure_context, ), script_chan, task_manager, diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 8be356e5ea2..e37e561af06 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -307,6 +307,7 @@ impl WindowProxy { None, document.global().get_referrer(), document.get_referrer_policy(), + None, // Doesn't inherit secure context ); let load_info = AuxiliaryBrowsingContextLoadInfo { load_data: load_data.clone(), @@ -511,12 +512,14 @@ impl WindowProxy { // Step 14.5 let referrer_policy = target_document.get_referrer_policy(); let pipeline_id = target_window.upcast::<GlobalScope>().pipeline_id(); + let secure = target_window.upcast::<GlobalScope>().is_secure_context(); let load_data = LoadData::new( LoadOrigin::Script(existing_document.origin().immutable().clone()), url, Some(pipeline_id), referrer, referrer_policy, + Some(secure), ); let replacement_flag = if new { HistoryEntryReplacement::Enabled diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index aabda0ab248..6092b3c4c3e 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -80,8 +80,10 @@ pub fn prepare_workerscope_init( worker_id: worker_id.unwrap_or_else(|| WorkerId(Uuid::new_v4())), pipeline_id: global.pipeline_id(), origin: global.origin().immutable().clone(), + creation_url: global.creation_url().clone(), is_headless: global.is_headless(), user_agent: global.get_user_agent(), + inherited_secure_context: Some(global.is_secure_context()), }; init @@ -141,10 +143,12 @@ impl WorkerGlobalScope { init.scheduler_chan, init.resource_threads, MutableOrigin::new(init.origin), + init.creation_url, runtime.microtask_queue.clone(), init.is_headless, init.user_agent, gpu_id_hub, + init.inherited_secure_context, ), worker_id: init.worker_id, worker_name, @@ -405,6 +409,11 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope { .ascii_serialization(), ) } + + // https://w3c.github.io/webappsec-secure-contexts/#dom-windoworworkerglobalscope-issecurecontext + fn IsSecureContext(&self) -> bool { + self.upcast::<GlobalScope>().is_secure_context() + } } impl WorkerGlobalScope { diff --git a/components/script/dom/workletglobalscope.rs b/components/script/dom/workletglobalscope.rs index 47e6315c940..29d5b9b7f99 100644 --- a/components/script/dom/workletglobalscope.rs +++ b/components/script/dom/workletglobalscope.rs @@ -71,10 +71,12 @@ impl WorkletGlobalScope { init.scheduler_chan.clone(), init.resource_threads.clone(), MutableOrigin::new(ImmutableOrigin::new_opaque()), + None, Default::default(), init.is_headless, init.user_agent.clone(), init.gpu_id_hub.clone(), + init.inherited_secure_context, ), base_url, to_script_thread_sender: init.to_script_thread_sender.clone(), @@ -166,6 +168,8 @@ pub struct WorkletGlobalScopeInit { pub user_agent: Cow<'static, str>, /// Identity manager for WebGPU resources pub gpu_id_hub: Arc<Mutex<Identities>>, + /// Is considered secure + pub inherited_secure_context: Option<bool>, } /// <https://drafts.css-houdini.org/worklets/#worklet-global-scope-type> diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 16de38f0265..b41c5885c83 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -216,6 +216,8 @@ struct InProgressLoad { canceller: FetchCanceller, /// Flag for sharing with the layout thread that is not yet created. layout_is_busy: Arc<AtomicBool>, + /// If inheriting the security context + inherited_secure_context: Option<bool>, } impl InProgressLoad { @@ -231,6 +233,7 @@ impl InProgressLoad { url: ServoUrl, origin: MutableOrigin, layout_is_busy: Arc<AtomicBool>, + inherited_secure_context: Option<bool>, ) -> InProgressLoad { let current_time = get_time(); let navigation_start_precise = precise_time_ns(); @@ -253,6 +256,7 @@ impl InProgressLoad { navigation_start_precise: navigation_start_precise, canceller: Default::default(), layout_is_busy: layout_is_busy, + inherited_secure_context: inherited_secure_context, } } } @@ -692,6 +696,9 @@ pub struct ScriptThread { /// Receiver to receive commands from optional WebGPU server. webgpu_port: RefCell<Option<Receiver<WebGPUMsg>>>, + + // Secure context + inherited_secure_context: Option<bool>, } struct BHMExitSignal { @@ -778,6 +785,7 @@ impl ScriptThreadFactory for ScriptThread { let top_level_browsing_context_id = state.top_level_browsing_context_id; let parent_info = state.parent_info; let opener = state.opener; + let secure = load_data.inherited_secure_context.clone(); let mem_profiler_chan = state.mem_profiler_chan.clone(); let window_size = state.window_size; let layout_is_busy = state.layout_is_busy.clone(); @@ -816,6 +824,7 @@ impl ScriptThreadFactory for ScriptThread { load_data.url.clone(), origin, layout_is_busy, + secure, ); script_thread.pre_page_load(new_load, load_data); @@ -1149,6 +1158,7 @@ impl ScriptThread { is_headless: script_thread.headless, user_agent: script_thread.user_agent.clone(), gpu_id_hub: script_thread.gpu_id_hub.clone(), + inherited_secure_context: script_thread.inherited_secure_context.clone(), }; Rc::new(WorkletThreadPool::spawn(init)) }) @@ -1404,6 +1414,7 @@ impl ScriptThread { is_user_interacting: Cell::new(false), gpu_id_hub: Arc::new(Mutex::new(Identities::new())), webgpu_port: RefCell::new(None), + inherited_secure_context: state.inherited_secure_context, } } @@ -2523,6 +2534,7 @@ impl ScriptThread { load_data.url.clone(), origin, layout_is_busy.clone(), + load_data.inherited_secure_context.clone(), ); if load_data.url.as_str() == "about:blank" { self.start_page_load_about_blank(new_load, load_data.js_eval_result); @@ -3271,6 +3283,7 @@ impl ScriptThread { incomplete.parent_info, incomplete.window_size, origin.clone(), + final_url.clone(), incomplete.navigation_start, incomplete.navigation_start_precise, self.webgl_chan.as_ref().map(|chan| chan.channel()), @@ -3290,6 +3303,7 @@ impl ScriptThread { self.player_context.clone(), self.event_loop_waker.as_ref().map(|w| (*w).clone_box()), self.gpu_id_hub.clone(), + incomplete.inherited_secure_context, ); // Initialize the browsing context for the window. diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 1087e37a9fc..be926307bd9 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -182,6 +182,8 @@ pub struct LoadData { /// The source to use instead of a network response for a srcdoc document. pub srcdoc: String, + /// The inherited context is Secure, None if not inherited + pub inherited_secure_context: Option<bool>, } /// The result of evaluating a javascript scheme url. @@ -202,6 +204,7 @@ impl LoadData { creator_pipeline_id: Option<PipelineId>, referrer: Referrer, referrer_policy: Option<ReferrerPolicy>, + inherited_secure_context: Option<bool>, ) -> LoadData { LoadData { load_origin, @@ -214,6 +217,7 @@ impl LoadData { referrer: referrer, referrer_policy: referrer_policy, srcdoc: "".to_string(), + inherited_secure_context, } } } @@ -639,6 +643,8 @@ pub struct InitialScriptState { pub top_level_browsing_context_id: TopLevelBrowsingContextId, /// The ID of the opener, if any. pub opener: Option<BrowsingContextId>, + /// Loading into a Secure Context + pub inherited_secure_context: Option<bool>, /// A channel with which messages can be sent to us (the script thread). pub control_chan: IpcSender<ConstellationControlMsg>, /// A port on which messages sent by the constellation to script can be received. @@ -751,6 +757,8 @@ pub struct IFrameLoadInfo { pub new_pipeline_id: PipelineId, /// Whether this iframe should be considered private pub is_private: bool, + /// Whether this iframe should be considered secure + pub inherited_secure_context: Option<bool>, /// Wether this load should replace the current entry (reload). If true, the current /// entry will be replaced instead of a new entry being added. pub replace: HistoryEntryReplacement, @@ -868,10 +876,14 @@ pub struct WorkerGlobalScopeInit { pub pipeline_id: PipelineId, /// The origin pub origin: ImmutableOrigin, + /// The creation URL + pub creation_url: Option<ServoUrl>, /// True if headless mode pub is_headless: bool, /// An optional string allowing the user agnet to be set for testing. pub user_agent: Cow<'static, str>, + /// True if secure context + pub inherited_secure_context: Option<bool>, } /// Common entities representing a network load origin diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs index 3b53127d0d9..645ea96e3f0 100644 --- a/components/webdriver_server/lib.rs +++ b/components/webdriver_server/lib.rs @@ -644,7 +644,14 @@ impl Handler { let top_level_browsing_context_id = self.session()?.top_level_browsing_context_id; - let load_data = LoadData::new(LoadOrigin::WebDriver, url, None, Referrer::NoReferrer, None); + let load_data = LoadData::new( + LoadOrigin::WebDriver, + url, + None, + Referrer::NoReferrer, + None, + None, + ); let cmd_msg = WebDriverCommandMsg::LoadUrl( top_level_browsing_context_id, load_data, |