| /* |
| * Copyright (C) 2008 Apple Inc. All Rights Reserved. |
| * Copyright (C) 2012 Google Inc. All Rights Reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| */ |
| |
| #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_EXECUTION_CONTEXT_H_ |
| #define THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_EXECUTION_CONTEXT_H_ |
| |
| #include <bitset> |
| #include <memory> |
| |
| #include "base/macros.h" |
| #include "base/optional.h" |
| #include "services/metrics/public/cpp/ukm_source_id.h" |
| #include "services/network/public/mojom/ip_address_space.mojom-blink-forward.h" |
| #include "services/network/public/mojom/referrer_policy.mojom-blink-forward.h" |
| #include "third_party/blink/public/common/tokens/tokens.h" |
| #include "third_party/blink/public/common/user_agent/user_agent_metadata.h" |
| #include "third_party/blink/public/mojom/devtools/inspector_issue.mojom-blink-forward.h" |
| #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink-forward.h" |
| #include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink-forward.h" |
| #include "third_party/blink/public/mojom/feature_policy/policy_disposition.mojom-blink-forward.h" |
| #include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink-forward.h" |
| #include "third_party/blink/public/mojom/v8_cache_options.mojom-blink.h" |
| #include "third_party/blink/public/platform/web_url_loader.h" |
| #include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h" |
| #include "third_party/blink/renderer/core/core_export.h" |
| #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" |
| #include "third_party/blink/renderer/core/execution_context/security_context.h" |
| #include "third_party/blink/renderer/core/frame/dom_timer_coordinator.h" |
| #include "third_party/blink/renderer/platform/context_lifecycle_notifier.h" |
| #include "third_party/blink/renderer/platform/heap/handle.h" |
| #include "third_party/blink/renderer/platform/heap_observer_set.h" |
| #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" |
| #include "third_party/blink/renderer/platform/loader/fetch/console_logger.h" |
| #include "third_party/blink/renderer/platform/loader/fetch/https_state.h" |
| #include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" |
| #include "third_party/blink/renderer/platform/runtime_enabled_features.h" |
| #include "third_party/blink/renderer/platform/supplementable.h" |
| #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" |
| #include "v8/include/v8.h" |
| |
| namespace base { |
| class UnguessableToken; |
| } // namespace base |
| |
| namespace ukm { |
| class UkmRecorder; |
| } // namespace ukm |
| |
| namespace blink { |
| |
| class Agent; |
| class ConsoleMessage; |
| class ContentSecurityPolicy; |
| class ContentSecurityPolicyDelegate; |
| class CoreProbeSink; |
| class DOMTimerCoordinator; |
| class DOMWrapperWorld; |
| class ErrorEvent; |
| class EventTarget; |
| class FrameOrWorkerScheduler; |
| class KURL; |
| class LocalDOMWindow; |
| class OriginTrialContext; |
| class PublicURLManager; |
| class ResourceFetcher; |
| class SecurityOrigin; |
| class ScriptState; |
| class ScriptWrappable; |
| class TrustedTypePolicyFactory; |
| |
| enum ReasonForCallingCanExecuteScripts { |
| kAboutToExecuteScript, |
| kNotAboutToExecuteScript |
| }; |
| |
| enum ReferrerPolicySource { kPolicySourceHttpHeader, kPolicySourceMetaTag }; |
| |
| // An environment in which script can execute. This class exposes the common |
| // properties of script execution environments on the web (i.e, common between |
| // script executing in a window and script executing in a worker), such as: |
| // |
| // - a base URL for the resolution of relative URLs |
| // - a security context that defines the privileges associated with the |
| // environment (note, however, that specific isolated script contexts may |
| // still enjoy elevated privileges) |
| // - affordances for the activity (including script and active DOM objects) to |
| // be paused or terminated, e.g. because a frame has entered the background or |
| // been closed permanently |
| // - a console logging facility for debugging |
| // |
| // Typically, the ExecutionContext is an instance of LocalDOMWindow or of |
| // WorkerOrWorkletGlobalScope. |
| // |
| // Note that this is distinct from the notion of a ScriptState or v8::Context, |
| // which are associated with a single script context (with a single global |
| // object). For example, there are separate JavaScript globals for "main world" |
| // script written by a web author and an "isolated world" content script written |
| // by an extension developer, but these share an ExecutionContext (the window) |
| // in common. |
| class CORE_EXPORT ExecutionContext : public Supplementable<ExecutionContext>, |
| public MojoBindingContext, |
| public ConsoleLogger, |
| public UseCounter, |
| public FeatureContext { |
| public: |
| void Trace(Visitor*) const override; |
| |
| static ExecutionContext* From(const ScriptState*); |
| static ExecutionContext* From(v8::Local<v8::Context>); |
| |
| // Returns the ExecutionContext of the current realm. |
| static ExecutionContext* ForCurrentRealm( |
| const v8::FunctionCallbackInfo<v8::Value>&); |
| static ExecutionContext* ForCurrentRealm( |
| const v8::PropertyCallbackInfo<v8::Value>&); |
| // Returns the ExecutionContext of the relevant realm for the receiver object. |
| static ExecutionContext* ForRelevantRealm( |
| const v8::FunctionCallbackInfo<v8::Value>&); |
| static ExecutionContext* ForRelevantRealm( |
| const v8::PropertyCallbackInfo<v8::Value>&); |
| |
| virtual bool IsWindow() const { return false; } |
| virtual bool IsWorkerOrWorkletGlobalScope() const { return false; } |
| virtual bool IsWorkerGlobalScope() const { return false; } |
| virtual bool IsWorkletGlobalScope() const { return false; } |
| virtual bool IsMainThreadWorkletGlobalScope() const { return false; } |
| virtual bool IsDedicatedWorkerGlobalScope() const { return false; } |
| virtual bool IsSharedWorkerGlobalScope() const { return false; } |
| virtual bool IsServiceWorkerGlobalScope() const { return false; } |
| virtual bool IsAnimationWorkletGlobalScope() const { return false; } |
| virtual bool IsAudioWorkletGlobalScope() const { return false; } |
| virtual bool IsLayoutWorkletGlobalScope() const { return false; } |
| virtual bool IsPaintWorkletGlobalScope() const { return false; } |
| virtual bool IsThreadedWorkletGlobalScope() const { return false; } |
| virtual bool IsJSExecutionForbidden() const { return false; } |
| |
| virtual bool IsContextThread() const { return true; } |
| |
| virtual bool ShouldInstallV8Extensions() const { return false; } |
| |
| const SecurityOrigin* GetSecurityOrigin() const; |
| SecurityOrigin* GetMutableSecurityOrigin(); |
| |
| ContentSecurityPolicy* GetContentSecurityPolicy() const; |
| |
| network::mojom::blink::WebSandboxFlags GetSandboxFlags() const; |
| bool IsSandboxed(network::mojom::blink::WebSandboxFlags mask) const; |
| |
| // Returns a reference to the current world we are in. If the current v8 |
| // context is empty, returns null. |
| scoped_refptr<const DOMWrapperWorld> GetCurrentWorld() const; |
| |
| // Returns the content security policy to be used based on the current |
| // JavaScript world we are in. |
| ContentSecurityPolicy* GetContentSecurityPolicyForCurrentWorld(); |
| |
| // Returns the content security policy to be used for the given |world|. |
| virtual ContentSecurityPolicy* GetContentSecurityPolicyForWorld( |
| const DOMWrapperWorld* world); |
| |
| virtual const KURL& Url() const = 0; |
| virtual const KURL& BaseURL() const = 0; |
| virtual KURL CompleteURL(const String& url) const = 0; |
| virtual void DisableEval(const String& error_message) = 0; |
| virtual String UserAgent() const = 0; |
| virtual UserAgentMetadata GetUserAgentMetadata() const { |
| return UserAgentMetadata(); |
| } |
| |
| virtual HttpsState GetHttpsState() const = 0; |
| |
| // Gets the DOMTimerCoordinator which maintains the "active timer |
| // list" of tasks created by setTimeout and setInterval. The |
| // DOMTimerCoordinator is owned by the ExecutionContext and should |
| // not be used after the ExecutionContext is destroyed. |
| DOMTimerCoordinator* Timers() { |
| DCHECK(!IsWorkletGlobalScope()); |
| return &timers_; |
| } |
| |
| virtual ResourceFetcher* Fetcher() const = 0; |
| |
| SecurityContext& GetSecurityContext() { return security_context_; } |
| const SecurityContext& GetSecurityContext() const { |
| return security_context_; |
| } |
| |
| // https://tc39.github.io/ecma262/#sec-agent-clusters |
| const base::UnguessableToken& GetAgentClusterID() const; |
| |
| bool IsSameAgentCluster(const base::UnguessableToken&) const; |
| |
| virtual bool CanExecuteScripts(ReasonForCallingCanExecuteScripts) { |
| return false; |
| } |
| virtual mojom::blink::V8CacheOptions GetV8CacheOptions() const { |
| return mojom::blink::V8CacheOptions::kDefault; |
| } |
| |
| void DispatchErrorEvent(ErrorEvent*, SanitizeScriptErrors); |
| |
| virtual void ExceptionThrown(ErrorEvent*) = 0; |
| |
| PublicURLManager& GetPublicURLManager(); |
| |
| ContentSecurityPolicyDelegate& GetContentSecurityPolicyDelegate(); |
| |
| virtual void RemoveURLFromMemoryCache(const KURL&); |
| |
| void SetIsInBackForwardCache(bool); |
| void SetLifecycleState(mojom::FrameLifecycleState); |
| void NotifyContextDestroyed(); |
| |
| using ConsoleLogger::AddConsoleMessage; |
| |
| void AddConsoleMessage(ConsoleMessage* message, |
| bool discard_duplicates = false) { |
| AddConsoleMessageImpl(message, discard_duplicates); |
| } |
| virtual void AddInspectorIssue(mojom::blink::InspectorIssueInfoPtr) = 0; |
| |
| bool IsContextPaused() const; |
| WebURLLoader::DeferType DeferType() const; |
| bool IsContextDestroyed() const { return is_context_destroyed_; } |
| mojom::FrameLifecycleState ContextPauseState() const { |
| return lifecycle_state_; |
| } |
| bool IsLoadDeferred() const; |
| |
| // Gets the next id in a circular sequence from 1 to 2^31-1. |
| int CircularSequentialID(); |
| |
| virtual EventTarget* ErrorEventTarget() = 0; |
| |
| // Methods related to window interaction. It should be used to manage window |
| // focusing and window creation permission for an ExecutionContext. |
| void AllowWindowInteraction(); |
| void ConsumeWindowInteraction(); |
| bool IsWindowInteractionAllowed() const; |
| |
| // Decides whether this context is privileged, as described in |
| // https://w3c.github.io/webappsec-secure-contexts/#is-settings-object-contextually-secure. |
| SecureContextMode GetSecureContextMode() const { |
| return security_context_.GetSecureContextMode(); |
| } |
| bool IsSecureContext() const { |
| return GetSecureContextMode() == SecureContextMode::kSecureContext; |
| } |
| bool IsSecureContext(String& error_message) const; |
| |
| virtual bool HasInsecureContextInAncestors() { return false; } |
| |
| // Returns a referrer to be used in the "Determine request's Referrer" |
| // algorithm defined in the Referrer Policy spec. |
| // https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer |
| virtual String OutgoingReferrer() const; |
| |
| // Parses a referrer policy directive using either Header or Meta rules and |
| // sets the context to use that policy. If the supplied policy is invalid, |
| // the context's policy is unchanged and a message is logged to the console. |
| // |
| // For a header-set policy, parses a comma-delimited list of tokens, and sets |
| // the context's policy to the last one that is a valid policy. For a meta-set |
| // policy, accepts only a single token, and allows the legacy tokens defined |
| // in the HTML specification. |
| void ParseAndSetReferrerPolicy(const String& policy, |
| ReferrerPolicySource source); |
| void SetReferrerPolicy(network::mojom::ReferrerPolicy); |
| virtual network::mojom::ReferrerPolicy GetReferrerPolicy() const { |
| return referrer_policy_; |
| } |
| |
| virtual CoreProbeSink* GetProbeSink() { return nullptr; } |
| |
| virtual FrameOrWorkerScheduler* GetScheduler() = 0; |
| |
| v8::Isolate* GetIsolate() const { return isolate_; } |
| Agent* GetAgent() const { return agent_; } |
| |
| v8::MicrotaskQueue* GetMicrotaskQueue() const; |
| |
| OriginTrialContext* GetOriginTrialContext() const { |
| return origin_trial_context_; |
| } |
| |
| virtual TrustedTypePolicyFactory* GetTrustedTypes() const { return nullptr; } |
| virtual bool RequireTrustedTypes() const; |
| |
| // FeatureContext override |
| bool FeatureEnabled(OriginTrialFeature) const override; |
| |
| // Tests whether the policy-controlled feature is enabled in this frame. |
| // Optionally sends a report to any registered reporting observers or |
| // Report-To endpoints, via ReportFeaturePolicyViolation(), if the feature is |
| // disabled. The optional ConsoleMessage will be sent to the console if |
| // present, or else a default message will be used instead. |
| bool IsFeatureEnabled( |
| mojom::blink::FeaturePolicyFeature, |
| ReportOptions report_on_failure = ReportOptions::kDoNotReport, |
| const String& message = g_empty_string) const; |
| bool IsFeatureEnabled( |
| mojom::blink::DocumentPolicyFeature, |
| ReportOptions report_option = ReportOptions::kDoNotReport, |
| const String& message = g_empty_string, |
| const String& source_file = g_empty_string) const; |
| bool IsFeatureEnabled( |
| mojom::blink::DocumentPolicyFeature, |
| PolicyValue threshold_value, |
| ReportOptions report_option = ReportOptions::kDoNotReport, |
| const String& message = g_empty_string, |
| const String& source_file = g_empty_string) const; |
| |
| virtual void CountPotentialFeaturePolicyViolation( |
| mojom::blink::FeaturePolicyFeature) const {} |
| |
| // Report policy violations is delegated to Document because in order |
| // to both remain const qualified and output console message, needs |
| // to call |frame_->Console().AddMessage()| directly. |
| virtual void ReportFeaturePolicyViolation( |
| mojom::blink::FeaturePolicyFeature, |
| mojom::blink::PolicyDisposition, |
| const String& message = g_empty_string) const {} |
| virtual void ReportDocumentPolicyViolation( |
| mojom::blink::DocumentPolicyFeature, |
| mojom::blink::PolicyDisposition, |
| const String& message = g_empty_string, |
| const String& source_file = g_empty_string) const {} |
| |
| String addressSpaceForBindings() const; |
| void SetAddressSpace(network::mojom::IPAddressSpace space) { |
| address_space_ = space; |
| } |
| network::mojom::IPAddressSpace AddressSpace() const { return address_space_; } |
| |
| HeapObserverSet<ContextLifecycleObserver>& ContextLifecycleObserverSet() { |
| return ContextLifecycleNotifier::observers(); |
| } |
| unsigned ContextLifecycleStateObserverCountForTesting() const; |
| |
| // Implementation of WindowOrWorkerGlobalScope.crossOriginIsolated. |
| // https://html.spec.whatwg.org/C/webappapis.html#concept-settings-object-cross-origin-isolated-capability |
| virtual bool CrossOriginIsolatedCapability() const = 0; |
| |
| // Returns true if SharedArrayBuffers can be transferred via PostMessage, |
| // false otherwise. SharedArrayBuffer allows pages to craft high-precision |
| // timers useful for Spectre-style side channel attacks, so are restricted |
| // to cross-origin isolated contexts. |
| bool SharedArrayBufferTransferAllowed() const; |
| // Returns SharedArrayBufferTransferAllowed() but potentially reports an |
| // inspector issue if the transfer was disallowed, or will be disallowed in |
| // the future. |
| bool CheckSharedArrayBufferTransferAllowedAndReport(); |
| |
| virtual ukm::UkmRecorder* UkmRecorder() { return nullptr; } |
| virtual ukm::SourceId UkmSourceID() const { return ukm::kInvalidSourceId; } |
| |
| // Returns the token that uniquely identifies this ExecutionContext. |
| virtual ExecutionContextToken GetExecutionContextToken() const = 0; |
| |
| // Returns the token that uniquely identifies the parent ExecutionContext of |
| // this context. If an ExecutionContext has a parent context, it means that it |
| // was created from that context, and the lifetime of this context is tied to |
| // the lifetime of its parent. This is used for resource usage attribution, |
| // where the resource usage of a child context will be charged to its parent |
| // (and so on up the tree). |
| virtual base::Optional<ExecutionContextToken> GetParentExecutionContextToken() |
| const { |
| return base::nullopt; |
| } |
| |
| // ExecutionContext subclasses are usually the V8 global object, which means |
| // they are also a ScriptWrappable. This casts the ExecutionContext to a |
| // ScriptWrappable if possible. |
| virtual ScriptWrappable* ToScriptWrappable() { |
| NOTREACHED(); |
| return nullptr; |
| } |
| |
| bool has_filed_shared_array_buffer_creation_issue() const { |
| return has_filed_shared_array_buffer_creation_issue_; |
| } |
| |
| void FileSharedArrayBufferCreationIssue(); |
| |
| protected: |
| explicit ExecutionContext(v8::Isolate* isolate, Agent*); |
| ExecutionContext(const ExecutionContext&) = delete; |
| ExecutionContext& operator=(const ExecutionContext&) = delete; |
| ~ExecutionContext() override; |
| |
| // Resetting the Agent is only necessary for a special case related to the |
| // GetShouldReuseGlobalForUnownedMainFrame() Setting. |
| void ResetAgent(Agent* agent) { agent_ = agent; } |
| |
| private: |
| // ConsoleLogger implementation. |
| void AddConsoleMessageImpl(mojom::ConsoleMessageSource, |
| mojom::ConsoleMessageLevel, |
| const String& message, |
| bool discard_duplicates) override; |
| virtual void AddConsoleMessageImpl(ConsoleMessage*, |
| bool discard_duplicates) = 0; |
| |
| v8::Isolate* const isolate_; |
| |
| SecurityContext security_context_; |
| |
| Member<Agent> agent_; |
| |
| bool DispatchErrorEventInternal(ErrorEvent*, SanitizeScriptErrors); |
| |
| unsigned circular_sequential_id_; |
| |
| bool in_dispatch_error_event_; |
| HeapVector<Member<ErrorEvent>> pending_exceptions_; |
| |
| mojom::FrameLifecycleState lifecycle_state_; |
| bool is_context_destroyed_; |
| |
| bool is_in_back_forward_cache_ = false; |
| |
| bool has_filed_shared_array_buffer_transfer_issue_ = false; |
| bool has_filed_shared_array_buffer_creation_issue_ = false; |
| |
| Member<PublicURLManager> public_url_manager_; |
| |
| const Member<ContentSecurityPolicyDelegate> csp_delegate_; |
| |
| DOMTimerCoordinator timers_; |
| |
| // Counter that keeps track of how many window interaction calls are allowed |
| // for this ExecutionContext. Callers are expected to call |
| // |allowWindowInteraction()| and |consumeWindowInteraction()| in order to |
| // increment and decrement the counter. |
| int window_interaction_tokens_; |
| |
| network::mojom::ReferrerPolicy referrer_policy_; |
| |
| network::mojom::blink::IPAddressSpace address_space_; |
| |
| Member<OriginTrialContext> origin_trial_context_; |
| }; |
| |
| } // namespace blink |
| |
| #endif // THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_EXECUTION_CONTEXT_H_ |