OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CONTENT_COMMON_FEATURE_POLICY_FEATURE_POLICY_H_ | 5 #ifndef CONTENT_COMMON_FEATURE_POLICY_FEATURE_POLICY_H_ |
6 #define CONTENT_COMMON_FEATURE_POLICY_FEATURE_POLICY_H_ | 6 #define CONTENT_COMMON_FEATURE_POLICY_FEATURE_POLICY_H_ |
7 | 7 |
| 8 #include <map> |
| 9 #include <memory> |
8 #include <string> | 10 #include <string> |
9 #include <vector> | 11 #include <vector> |
10 | 12 |
| 13 #include "base/macros.h" |
11 #include "content/common/content_export.h" | 14 #include "content/common/content_export.h" |
| 15 #include "third_party/WebKit/public/platform/WebFeaturePolicy.h" |
12 #include "url/origin.h" | 16 #include "url/origin.h" |
13 | 17 |
14 namespace content { | 18 namespace content { |
15 | 19 |
| 20 // Feature Policy is a mechanism for controlling the availability of web |
| 21 // platform features in a frame, including all embedded frames. It can be used |
| 22 // to remove features, automatically refuse API permission requests, or modify |
| 23 // the behaviour of features. (The specific changes which are made depend on the |
| 24 // feature; see the specification for details). |
| 25 // |
| 26 // Policies can be defined in the HTTP header stream, with the |Feature-Policy| |
| 27 // HTTP header, or can be set by the |allow| attributes on the iframe element |
| 28 // which embeds the document. |
| 29 // |
| 30 // See https://wicg.github.io/FeaturePolicy/ |
| 31 // |
| 32 // Key concepts: |
| 33 // |
| 34 // Features |
| 35 // -------- |
| 36 // Features which can be controlled by policy are defined by instances of the |
| 37 // FeaturePolicy::Feature struct. The features are referenced by the |
| 38 // |WebFeaturePolicyFeature| enum, declared in |WebFeaturePolicy.h|. |
| 39 // |
| 40 // Whitelists |
| 41 // ---------- |
| 42 // Whitelists are collections of origins, although two special terms can be used |
| 43 // when declaring them: |
| 44 // "self" refers to the orgin of the frame which is declaring the policy. |
| 45 // "*" refers to all origins; any origin will match a whitelist which contains |
| 46 // it. |
| 47 // |
| 48 // Declarations |
| 49 // ------------ |
| 50 // A feature policy declaration is a mapping of a feature name to a whitelist. |
| 51 // A set of declarations is a declared policy. |
| 52 // |
| 53 // Inherited Policy |
| 54 // ---------------- |
| 55 // In addition to the declared policy (which may be empty), every frame has |
| 56 // an inherited policy, which is determined by the context in which it is |
| 57 // embedded, or by the defaults for each feature in the case of the top-level |
| 58 // document. |
| 59 // |
| 60 // Defaults |
| 61 // -------- |
| 62 // Each defined feature has a default policy, which determines whether the |
| 63 // feature is available when no policy has been declared, ans determines how the |
| 64 // feature is inherited across origin boundaries. |
| 65 // |
| 66 // If the default policy is in effect for a frame, then it controls how the |
| 67 // feature is inherited by any cross-origin iframes embedded by the frame. (See |
| 68 // the comments below in FeaturePolicy::DefaultPolicy for specifics) |
| 69 // |
| 70 // Policy Inheritance |
| 71 // ------------------ |
| 72 // Policies in effect for a frame are inherited by any child frames it embeds. |
| 73 // Unless another policy is declared in the child, all same-origin children will |
| 74 // receive the same set of enables features as the parent frame. Whether or not |
| 75 // features are inherited by cross-origin iframes without an explicit policy is |
| 76 // determined by the feature's default policy. (Again, see the comments in |
| 77 // FeaturePolicy::DefaultPolicy for details) |
| 78 |
16 // This struct holds feature policy whitelist data that needs to be replicated | 79 // This struct holds feature policy whitelist data that needs to be replicated |
17 // between a RenderFrame and any of its associated RenderFrameProxies. A list of | 80 // between a RenderFrame and any of its associated RenderFrameProxies. A list of |
18 // these form a ParsedFeaturePolicyHeader. | 81 // these form a ParsedFeaturePolicyHeader. |
19 // NOTE: These types are used for replication frame state between processes. | 82 // NOTE: These types are used for replication frame state between processes. |
20 // They exist only because we can't transfer WebVectors directly over IPC. | 83 // They exist only because we can't transfer WebVectors directly over IPC. |
21 struct CONTENT_EXPORT ParsedFeaturePolicyDeclaration { | 84 struct CONTENT_EXPORT ParsedFeaturePolicyDeclaration { |
22 ParsedFeaturePolicyDeclaration(); | 85 ParsedFeaturePolicyDeclaration(); |
23 ParsedFeaturePolicyDeclaration(std::string feature_name, | 86 ParsedFeaturePolicyDeclaration(std::string feature_name, |
24 bool matches_all_origins, | 87 bool matches_all_origins, |
25 std::vector<url::Origin> origins); | 88 std::vector<url::Origin> origins); |
26 ParsedFeaturePolicyDeclaration(const ParsedFeaturePolicyDeclaration& rhs); | 89 ParsedFeaturePolicyDeclaration(const ParsedFeaturePolicyDeclaration& rhs); |
27 ~ParsedFeaturePolicyDeclaration(); | 90 ~ParsedFeaturePolicyDeclaration(); |
28 | 91 |
29 std::string feature_name; | 92 std::string feature_name; |
30 bool matches_all_origins; | 93 bool matches_all_origins; |
31 std::vector<url::Origin> origins; | 94 std::vector<url::Origin> origins; |
32 }; | 95 }; |
33 | 96 |
34 using ParsedFeaturePolicyHeader = std::vector<ParsedFeaturePolicyDeclaration>; | 97 using ParsedFeaturePolicyHeader = std::vector<ParsedFeaturePolicyDeclaration>; |
35 | 98 |
| 99 class CONTENT_EXPORT FeaturePolicy { |
| 100 public: |
| 101 // Represents a collection of origins which make up a whitelist in a feature |
| 102 // policy. This collection may be set to match every origin (corresponding to |
| 103 // the "*" syntax in the policy string, in which case the Contains() method |
| 104 // will always return true. |
| 105 class Whitelist final { |
| 106 public: |
| 107 Whitelist(); |
| 108 ~Whitelist(); |
| 109 |
| 110 // Adds a single origin to the whitelist. |
| 111 void Add(const url::Origin& origin); |
| 112 |
| 113 // Adds all origins to the whitelist. |
| 114 void AddAll(); |
| 115 |
| 116 // Returns true if the given origin has been added to the whitelist. |
| 117 bool Contains(const url::Origin& origin) const; |
| 118 |
| 119 private: |
| 120 bool matches_all_origins_; |
| 121 std::vector<url::Origin> origins_; |
| 122 }; |
| 123 |
| 124 // The FeaturePolicy::FeatureDefault enum defines the default enable state for |
| 125 // a feature when neither it nor any parent frame have declared an explicit |
| 126 // policy. The three possibilities map directly to Feature Policy Whitelist |
| 127 // semantics. |
| 128 enum class FeatureDefault { |
| 129 // Equivalent to []. If this default policy is in effect for a frame, then |
| 130 // the feature will not be enabled for that frame or any of its children. |
| 131 DisableForAll, |
| 132 |
| 133 // Equivalent to ["self"]. If this default policy is in effect for a frame, |
| 134 // then the feature will be enabled for that frame, and any same-origin |
| 135 // child frames, but not for any cross-origin child frames. |
| 136 EnableForSelf, |
| 137 |
| 138 // Equivalent to ["*"]. If in effect for a frame, then the feature is |
| 139 // enabled for that frame and all of its children. |
| 140 EnableForAll |
| 141 }; |
| 142 |
| 143 // The FeaturePolicy::Feature struct is used to define all features under |
| 144 // control of Feature Policy. There should only be one instance of this struct |
| 145 // for any given feature (declared below). |
| 146 struct Feature { |
| 147 // The name of the feature, as it should appear in a policy string |
| 148 const char* const feature_name; |
| 149 |
| 150 // Controls whether the feature should be available in the platform by |
| 151 // default, in the absence of any declared policy. |
| 152 FeatureDefault default_policy; |
| 153 }; |
| 154 |
| 155 using FeatureList = |
| 156 std::map<blink::WebFeaturePolicyFeature, const FeaturePolicy::Feature*>; |
| 157 |
| 158 ~FeaturePolicy(); |
| 159 |
| 160 static std::unique_ptr<FeaturePolicy> CreateFromParentPolicy( |
| 161 const FeaturePolicy* parent_policy, |
| 162 const url::Origin& origin); |
| 163 |
| 164 // Returns whether or not the given feature is enabled by this policy. |
| 165 bool IsFeatureEnabledForOrigin(blink::WebFeaturePolicyFeature feature, |
| 166 const url::Origin& origin) const; |
| 167 |
| 168 // Returns whether or not the given feature is enabled for the origin of the |
| 169 // document that owns the policy. |
| 170 bool IsFeatureEnabled(blink::WebFeaturePolicyFeature feature) const; |
| 171 |
| 172 // Sets the declared policy from the parsed Feature-Policy HTTP header. |
| 173 // Unrecognized features will be ignored. |
| 174 void SetHeaderPolicy(const ParsedFeaturePolicyHeader& parsed_header); |
| 175 |
| 176 private: |
| 177 friend class FeaturePolicyTest; |
| 178 |
| 179 explicit FeaturePolicy(url::Origin origin); |
| 180 FeaturePolicy(url::Origin origin, const FeatureList& feature_list); |
| 181 static std::unique_ptr<FeaturePolicy> CreateFromParentPolicy( |
| 182 const FeaturePolicy* parent_policy, |
| 183 const url::Origin& origin, |
| 184 const FeatureList& features); |
| 185 |
| 186 // Returns the list of features which can be controlled by Feature Policy. |
| 187 static const FeatureList& GetDefaultFeatureList(); |
| 188 |
| 189 url::Origin origin_; |
| 190 |
| 191 // Map of feature names to declared whitelists. Any feature which is missing |
| 192 // from this map should use the inherited policy. |
| 193 std::map<blink::WebFeaturePolicyFeature, std::unique_ptr<Whitelist>> |
| 194 whitelists_; |
| 195 |
| 196 // Records whether or not each feature was enabled for this frame by its |
| 197 // parent frame. |
| 198 // TODO(iclelland): Generate, instead of this map, a set of bool flags, one |
| 199 // for each feature, as all features are supposed to be represented here. |
| 200 std::map<blink::WebFeaturePolicyFeature, bool> inherited_policies_; |
| 201 |
| 202 const FeatureList& feature_list_; |
| 203 |
| 204 DISALLOW_COPY_AND_ASSIGN(FeaturePolicy); |
| 205 }; |
| 206 |
36 } // namespace content | 207 } // namespace content |
37 | 208 |
38 #endif // CONTENT_COMMON_FEATURE_POLICY_FEATURE_POLICY_H_ | 209 #endif // CONTENT_COMMON_FEATURE_POLICY_FEATURE_POLICY_H_ |
OLD | NEW |