| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_FEATURE_POLICY_FEATURE_POLICY_H_ |
| #define THIRD_PARTY_BLINK_PUBLIC_COMMON_FEATURE_POLICY_FEATURE_POLICY_H_ |
| |
| #include <map> |
| #include <vector> |
| |
| #include "base/macros.h" |
| #include "services/network/public/mojom/web_sandbox_flags.mojom-shared.h" |
| #include "third_party/blink/public/common/common_export.h" |
| #include "third_party/blink/public/common/feature_policy/feature_policy_features.h" |
| #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-forward.h" |
| #include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-forward.h" |
| #include "url/origin.h" |
| |
| namespace blink { |
| |
| // Feature Policy is a mechanism for controlling the availability of web |
| // platform features in a frame, including all embedded frames. It can be used |
| // to remove features, automatically refuse API permission requests, or modify |
| // the behaviour of features. (The specific changes which are made depend on the |
| // feature; see the specification for details). |
| // |
| // Policies can be defined in the HTTP header stream, with the |Feature-Policy| |
| // HTTP header, or can be set by the |allow| attributes on the iframe element |
| // which embeds the document. |
| // |
| // See https://w3c.github.io/webappsec-permissions-policy/ |
| // |
| // Key concepts: |
| // |
| // Features |
| // -------- |
| // Features which can be controlled by policy are defined by instances of enum |
| // mojom::FeaturePolicyFeature, declared in |feature_policy.mojom|. |
| // |
| // Allowlists |
| // ---------- |
| // Allowlists are collections of origins, although several special terms can be |
| // used when declaring them: |
| // "none" indicates that no origins should be included in the allowlist. |
| // "self" refers to the origin of the frame which is declaring the policy. |
| // "src" refers to the origin specified by the attributes of the iframe |
| // element which embeds the document. This incorporates the src, srcdoc, and |
| // sandbox attributes. |
| // "*" refers to all origins; any origin will match an allowlist which |
| // contains it. |
| // |
| // Declarations |
| // ------------ |
| // A feature policy declaration is a mapping of a feature name to an allowlist. |
| // A set of declarations is a declared policy. |
| // |
| // Inherited Policy |
| // ---------------- |
| // In addition to the declared policy (which may be empty), every frame has |
| // an inherited policy, which is determined by the context in which it is |
| // embedded, or by the defaults for each feature in the case of the top-level |
| // document. |
| // |
| // Container Policy |
| // ---------------- |
| // A declared policy can be set on a specific frame by the embedding page using |
| // the iframe "allow" attribute, or through attributes such as "allowfullscreen" |
| // or "allowpaymentrequest". This is the container policy for the embedded |
| // frame. |
| // |
| // Defaults |
| // -------- |
| // Each defined feature has a default policy, which determines whether the |
| // feature is available when no policy has been declared, and determines how the |
| // feature is inherited across origin boundaries. |
| // |
| // If the default policy is in effect for a frame, then it controls how the |
| // feature is inherited by any cross-origin iframes embedded by the frame. (See |
| // the comments in |FeaturePolicyFeatureDefault| in feature_policy_features.h |
| // for specifics.) |
| // |
| // Policy Inheritance |
| // ------------------ |
| // Policies in effect for a frame are inherited by any child frames it embeds. |
| // Unless another policy is declared in the child, all same-origin children will |
| // receive the same set of enabled features as the parent frame. Whether or not |
| // features are inherited by cross-origin iframes without an explicit policy is |
| // determined by the feature's default policy. (Again, see the comments in |
| // |FeaturePolicyFeatureDefault| in feature_policy_features.h for details) |
| |
| // This struct holds feature policy allowlist data that needs to be replicated |
| // between a RenderFrame and any of its associated RenderFrameProxies. A list of |
| // these form a ParsedFeaturePolicy. |
| // NOTE: These types are used for replication frame state between processes. |
| struct BLINK_COMMON_EXPORT ParsedFeaturePolicyDeclaration { |
| ParsedFeaturePolicyDeclaration(); |
| explicit ParsedFeaturePolicyDeclaration(mojom::FeaturePolicyFeature feature); |
| ParsedFeaturePolicyDeclaration(mojom::FeaturePolicyFeature feature, |
| const std::vector<url::Origin>& values, |
| bool matches_all_origins, |
| bool matches_opaque_src); |
| ParsedFeaturePolicyDeclaration(const ParsedFeaturePolicyDeclaration& rhs); |
| ParsedFeaturePolicyDeclaration& operator=( |
| const ParsedFeaturePolicyDeclaration& rhs); |
| ~ParsedFeaturePolicyDeclaration(); |
| |
| mojom::FeaturePolicyFeature feature; |
| |
| // An alphabetically sorted list of all the origins allowed. |
| std::vector<url::Origin> allowed_origins; |
| // Fallback value is used when feature is enabled for all or disabled for all. |
| bool matches_all_origins{false}; |
| // This flag is set true for a declared policy on an <iframe sandbox> |
| // container, for a feature which is supposed to be allowed in the sandboxed |
| // document. Usually, the 'src' keyword in a declaration will cause the origin |
| // of the iframe to be present in |origins|, but for sandboxed iframes, this |
| // flag is set instead. |
| bool matches_opaque_src{false}; |
| }; |
| |
| using ParsedFeaturePolicy = std::vector<ParsedFeaturePolicyDeclaration>; |
| |
| bool BLINK_COMMON_EXPORT operator==(const ParsedFeaturePolicyDeclaration& lhs, |
| const ParsedFeaturePolicyDeclaration& rhs); |
| |
| class BLINK_COMMON_EXPORT FeaturePolicy { |
| public: |
| // Represents a collection of origins which make up an allowlist in a feature |
| // policy. This collection may be set to match every origin (corresponding to |
| // the "*" syntax in the policy string, in which case the Contains() method |
| // will always return true. |
| class BLINK_COMMON_EXPORT Allowlist final { |
| public: |
| Allowlist(); |
| Allowlist(const Allowlist& rhs); |
| ~Allowlist(); |
| |
| // Adds a single origin to the allowlist. |
| void Add(const url::Origin& origin); |
| |
| // Adds all origins to the allowlist. |
| void AddAll(); |
| |
| // Sets the allowlist to match the opaque origin implied by the 'src' |
| // keyword. |
| void AddOpaqueSrc(); |
| |
| // Returns true if the given origin has been added to the allowlist. |
| bool Contains(const url::Origin& origin) const; |
| |
| // Returns true if the allowlist matches all origins. |
| bool MatchesAll() const; |
| |
| // Returns true if the allowlist should match the opaque origin implied by |
| // the 'src' keyword. |
| bool MatchesOpaqueSrc() const; |
| |
| const std::vector<url::Origin>& AllowedOrigins() const { |
| return allowed_origins_; |
| } |
| |
| private: |
| std::vector<url::Origin> allowed_origins_; |
| bool matches_all_origins_{false}; |
| bool matches_opaque_src_{false}; |
| }; |
| |
| ~FeaturePolicy(); |
| |
| static std::unique_ptr<FeaturePolicy> CreateFromParentPolicy( |
| const FeaturePolicy* parent_policy, |
| const ParsedFeaturePolicy& container_policy, |
| const url::Origin& origin); |
| |
| static std::unique_ptr<FeaturePolicy> CopyStateFrom(const FeaturePolicy*); |
| |
| bool IsFeatureEnabled(mojom::FeaturePolicyFeature feature) const; |
| |
| // Returns whether or not the given feature is enabled by this policy for a |
| // specific origin. |
| bool IsFeatureEnabledForOrigin(mojom::FeaturePolicyFeature feature, |
| const url::Origin& origin) const; |
| |
| const Allowlist GetAllowlistForDevTools( |
| mojom::FeaturePolicyFeature feature) const; |
| |
| // Returns the allowlist of a given feature by this policy. |
| // TODO(crbug.com/937131): Use |FeaturePolicy::GetAllowlistForDevTools| |
| // to replace this method. This method uses legacy |default_allowlist| |
| // calculation method. |
| const Allowlist GetAllowlistForFeature( |
| mojom::FeaturePolicyFeature feature) const; |
| |
| // Sets the declared policy from the parsed Feature-Policy HTTP header. |
| // Unrecognized features will be ignored. |
| void SetHeaderPolicy(const ParsedFeaturePolicy& parsed_header); |
| |
| // Returns the current state of feature policies for |origin_|. This includes |
| // the |inherited_policies_| as well as the header policies. |
| FeaturePolicyFeatureState GetFeatureState() const; |
| |
| const url::Origin& GetOriginForTest() const { return origin_; } |
| |
| // Returns the list of features which can be controlled by Feature Policy. |
| const FeaturePolicyFeatureList& GetFeatureList() const; |
| |
| bool IsFeatureEnabledByInheritedPolicy( |
| mojom::FeaturePolicyFeature feature) const; |
| |
| private: |
| friend class FeaturePolicyTest; |
| |
| FeaturePolicy(url::Origin origin, |
| const FeaturePolicyFeatureList& feature_list); |
| static std::unique_ptr<FeaturePolicy> CreateFromParentPolicy( |
| const FeaturePolicy* parent_policy, |
| const ParsedFeaturePolicy& container_policy, |
| const url::Origin& origin, |
| const FeaturePolicyFeatureList& features); |
| |
| bool InheritedValueForFeature( |
| const FeaturePolicy* parent_policy, |
| std::pair<mojom::FeaturePolicyFeature, FeaturePolicyFeatureDefault> |
| feature, |
| const ParsedFeaturePolicy& container_policy) const; |
| |
| // Returns the value of the given feature on the given origin. |
| bool GetFeatureValueForOrigin(mojom::FeaturePolicyFeature feature, |
| const url::Origin& origin) const; |
| |
| // The origin of the document with which this policy is associated. |
| url::Origin origin_; |
| |
| // Map of feature names to declared allowlists. Any feature which is missing |
| // from this map should use the inherited policy. |
| std::map<mojom::FeaturePolicyFeature, Allowlist> allowlists_; |
| |
| // Records whether or not each feature was enabled for this frame by its |
| // parent frame. |
| FeaturePolicyFeatureState inherited_policies_; |
| |
| const FeaturePolicyFeatureList& feature_list_; |
| |
| DISALLOW_COPY_AND_ASSIGN(FeaturePolicy); |
| }; |
| |
| } // namespace blink |
| |
| #endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_FEATURE_POLICY_FEATURE_POLICY_H_ |