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 #include "content/common/feature_policy/feature_policy.h" | 5 #include "content/common/feature_policy/feature_policy.h" |
6 | 6 |
7 #include "base/macros.h" | 7 #include "base/macros.h" |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 | 10 |
11 namespace content { | 11 namespace content { |
12 | 12 |
13 namespace { | 13 namespace { |
14 | 14 |
15 // Given a string name, return the matching feature struct, or nullptr if it is | |
16 // not the name of a policy-controlled feature. | |
17 blink::WebFeaturePolicyFeature FeatureForName( | |
18 const std::string& feature_name, | |
19 const FeaturePolicy::FeatureList& features) { | |
20 for (const auto& feature_mapping : features) { | |
21 if (feature_name == feature_mapping.second->feature_name) | |
22 return feature_mapping.first; | |
23 } | |
24 return blink::WebFeaturePolicyFeature::NotFound; | |
25 } | |
26 | |
27 // Definitions of all features controlled by Feature Policy should appear here. | |
28 const FeaturePolicy::Feature kDocumentCookie{ | |
29 "cookie", FeaturePolicy::FeatureDefault::EnableForAll}; | |
30 const FeaturePolicy::Feature kDocumentDomain{ | |
31 "domain", FeaturePolicy::FeatureDefault::EnableForAll}; | |
32 const FeaturePolicy::Feature kDocumentWrite{ | |
33 "docwrite", FeaturePolicy::FeatureDefault::EnableForAll}; | |
34 const FeaturePolicy::Feature kFullscreenFeature{ | |
35 "fullscreen", FeaturePolicy::FeatureDefault::EnableForSelf}; | |
36 const FeaturePolicy::Feature kGeolocationFeature{ | |
37 "geolocation", FeaturePolicy::FeatureDefault::EnableForSelf}; | |
38 const FeaturePolicy::Feature kMidiFeature{ | |
39 "midi", FeaturePolicy::FeatureDefault::EnableForAll}; | |
40 const FeaturePolicy::Feature kNotificationsFeature{ | |
41 "notifications", FeaturePolicy::FeatureDefault::EnableForAll}; | |
42 const FeaturePolicy::Feature kPaymentFeature{ | |
43 "payment", FeaturePolicy::FeatureDefault::EnableForSelf}; | |
44 const FeaturePolicy::Feature kPushFeature{ | |
45 "push", FeaturePolicy::FeatureDefault::EnableForAll}; | |
46 const FeaturePolicy::Feature kSyncScript{ | |
47 "sync-script", FeaturePolicy::FeatureDefault::EnableForAll}; | |
48 const FeaturePolicy::Feature kSyncXHR{ | |
49 "sync-xhr", FeaturePolicy::FeatureDefault::EnableForAll}; | |
50 const FeaturePolicy::Feature kUsermedia{ | |
51 "usermedia", FeaturePolicy::FeatureDefault::EnableForAll}; | |
52 const FeaturePolicy::Feature kVibrateFeature{ | |
53 "vibrate", FeaturePolicy::FeatureDefault::EnableForSelf}; | |
54 const FeaturePolicy::Feature kWebRTC{ | |
55 "webrtc", FeaturePolicy::FeatureDefault::EnableForAll}; | |
56 | |
57 // Extracts a Whitelist from a ParsedFeaturePolicyDeclaration. | 15 // Extracts a Whitelist from a ParsedFeaturePolicyDeclaration. |
58 std::unique_ptr<FeaturePolicy::Whitelist> WhitelistFromDeclaration( | 16 std::unique_ptr<FeaturePolicy::Whitelist> WhitelistFromDeclaration( |
59 const ParsedFeaturePolicyDeclaration& parsed_declaration) { | 17 const ParsedFeaturePolicyDeclaration& parsed_declaration) { |
60 std::unique_ptr<FeaturePolicy::Whitelist> result = | 18 std::unique_ptr<FeaturePolicy::Whitelist> result = |
61 base::WrapUnique(new FeaturePolicy::Whitelist()); | 19 base::WrapUnique(new FeaturePolicy::Whitelist()); |
62 if (parsed_declaration.matches_all_origins) | 20 if (parsed_declaration.matches_all_origins) |
63 result->AddAll(); | 21 result->AddAll(); |
64 for (const auto& origin : parsed_declaration.origins) | 22 for (const auto& origin : parsed_declaration.origins) |
65 result->Add(origin); | 23 result->Add(origin); |
66 return result; | 24 return result; |
67 } | 25 } |
68 | 26 |
69 } // namespace | 27 } // namespace |
70 | 28 |
71 ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration() | 29 ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration() |
72 : matches_all_origins(false) {} | 30 : matches_all_origins(false) {} |
73 | 31 |
74 ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration( | 32 ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration( |
75 std::string feature_name, | 33 blink::WebFeaturePolicyFeature feature, |
76 bool matches_all_origins, | 34 bool matches_all_origins, |
77 std::vector<url::Origin> origins) | 35 std::vector<url::Origin> origins) |
78 : feature_name(feature_name), | 36 : feature(feature), |
79 matches_all_origins(matches_all_origins), | 37 matches_all_origins(matches_all_origins), |
80 origins(origins) {} | 38 origins(origins) {} |
81 | 39 |
82 ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration( | 40 ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration( |
83 const ParsedFeaturePolicyDeclaration& rhs) = default; | 41 const ParsedFeaturePolicyDeclaration& rhs) = default; |
84 | 42 |
85 ParsedFeaturePolicyDeclaration::~ParsedFeaturePolicyDeclaration() {} | 43 ParsedFeaturePolicyDeclaration::~ParsedFeaturePolicyDeclaration() {} |
86 | 44 |
87 FeaturePolicy::Whitelist::Whitelist() : matches_all_origins_(false) {} | 45 FeaturePolicy::Whitelist::Whitelist() : matches_all_origins_(false) {} |
88 | 46 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 | 97 |
140 bool FeaturePolicy::IsFeatureEnabled( | 98 bool FeaturePolicy::IsFeatureEnabled( |
141 blink::WebFeaturePolicyFeature feature) const { | 99 blink::WebFeaturePolicyFeature feature) const { |
142 return IsFeatureEnabledForOrigin(feature, origin_); | 100 return IsFeatureEnabledForOrigin(feature, origin_); |
143 } | 101 } |
144 | 102 |
145 bool FeaturePolicy::IsFeatureEnabledForOrigin( | 103 bool FeaturePolicy::IsFeatureEnabledForOrigin( |
146 blink::WebFeaturePolicyFeature feature, | 104 blink::WebFeaturePolicyFeature feature, |
147 const url::Origin& origin) const { | 105 const url::Origin& origin) const { |
148 DCHECK(base::ContainsKey(feature_list_, feature)); | 106 DCHECK(base::ContainsKey(feature_list_, feature)); |
149 const FeaturePolicy::Feature* feature_definition = feature_list_.at(feature); | 107 const FeaturePolicy::FeatureDefault default_policy = |
| 108 feature_list_.at(feature); |
150 DCHECK(base::ContainsKey(inherited_policies_, feature)); | 109 DCHECK(base::ContainsKey(inherited_policies_, feature)); |
151 if (!inherited_policies_.at(feature)) | 110 if (!inherited_policies_.at(feature)) |
152 return false; | 111 return false; |
153 auto whitelist = whitelists_.find(feature); | 112 auto whitelist = whitelists_.find(feature); |
154 if (whitelist != whitelists_.end()) | 113 if (whitelist != whitelists_.end()) |
155 return whitelist->second->Contains(origin); | 114 return whitelist->second->Contains(origin); |
156 if (feature_definition->default_policy == | 115 if (default_policy == FeaturePolicy::FeatureDefault::EnableForAll) { |
157 FeaturePolicy::FeatureDefault::EnableForAll) { | |
158 return true; | 116 return true; |
159 } | 117 } |
160 if (feature_definition->default_policy == | 118 if (default_policy == FeaturePolicy::FeatureDefault::EnableForSelf) { |
161 FeaturePolicy::FeatureDefault::EnableForSelf) { | |
162 // TODO(iclelland): Remove the pointer equality check once it is possible to | 119 // TODO(iclelland): Remove the pointer equality check once it is possible to |
163 // compare opaque origins successfully against themselves. | 120 // compare opaque origins successfully against themselves. |
164 // https://crbug.com/690520 | 121 // https://crbug.com/690520 |
165 return (&origin_ == &origin) || origin_.IsSameOriginWith(origin); | 122 return (&origin_ == &origin) || origin_.IsSameOriginWith(origin); |
166 } | 123 } |
167 return false; | 124 return false; |
168 } | 125 } |
169 | 126 |
170 void FeaturePolicy::SetHeaderPolicy( | 127 void FeaturePolicy::SetHeaderPolicy( |
171 const ParsedFeaturePolicyHeader& parsed_header) { | 128 const ParsedFeaturePolicyHeader& parsed_header) { |
172 DCHECK(whitelists_.empty()); | 129 DCHECK(whitelists_.empty()); |
173 for (const ParsedFeaturePolicyDeclaration& parsed_declaration : | 130 for (const ParsedFeaturePolicyDeclaration& parsed_declaration : |
174 parsed_header) { | 131 parsed_header) { |
175 blink::WebFeaturePolicyFeature feature = | 132 blink::WebFeaturePolicyFeature feature = parsed_declaration.feature; |
176 FeatureForName(parsed_declaration.feature_name, feature_list_); | 133 DCHECK(feature != blink::WebFeaturePolicyFeature::NotFound); |
177 if (feature == blink::WebFeaturePolicyFeature::NotFound) | |
178 continue; | |
179 whitelists_[feature] = WhitelistFromDeclaration(parsed_declaration); | 134 whitelists_[feature] = WhitelistFromDeclaration(parsed_declaration); |
180 } | 135 } |
181 } | 136 } |
182 | 137 |
183 FeaturePolicy::FeaturePolicy(url::Origin origin, | 138 FeaturePolicy::FeaturePolicy(url::Origin origin, |
184 const FeatureList& feature_list) | 139 const FeatureList& feature_list) |
185 : origin_(origin), feature_list_(feature_list) {} | 140 : origin_(origin), feature_list_(feature_list) {} |
186 | 141 |
187 FeaturePolicy::FeaturePolicy(url::Origin origin) | 142 FeaturePolicy::FeaturePolicy(url::Origin origin) |
188 : origin_(origin), feature_list_(GetDefaultFeatureList()) {} | 143 : origin_(origin), feature_list_(GetDefaultFeatureList()) {} |
(...skipping 23 matching lines...) Expand all Loading... |
212 | 167 |
213 void FeaturePolicy::AddContainerPolicy( | 168 void FeaturePolicy::AddContainerPolicy( |
214 const ParsedFeaturePolicyHeader& container_policy, | 169 const ParsedFeaturePolicyHeader& container_policy, |
215 const FeaturePolicy* parent_policy) { | 170 const FeaturePolicy* parent_policy) { |
216 DCHECK(parent_policy); | 171 DCHECK(parent_policy); |
217 for (const ParsedFeaturePolicyDeclaration& parsed_declaration : | 172 for (const ParsedFeaturePolicyDeclaration& parsed_declaration : |
218 container_policy) { | 173 container_policy) { |
219 // If a feature is enabled in the parent frame, and the parent chooses to | 174 // If a feature is enabled in the parent frame, and the parent chooses to |
220 // delegate it to the child frame, using the iframe attribute, then the | 175 // delegate it to the child frame, using the iframe attribute, then the |
221 // feature should be enabled in the child frame. | 176 // feature should be enabled in the child frame. |
222 blink::WebFeaturePolicyFeature feature = | 177 blink::WebFeaturePolicyFeature feature = parsed_declaration.feature; |
223 FeatureForName(parsed_declaration.feature_name, feature_list_); | |
224 if (feature == blink::WebFeaturePolicyFeature::NotFound) | 178 if (feature == blink::WebFeaturePolicyFeature::NotFound) |
225 continue; | 179 continue; |
226 if (WhitelistFromDeclaration(parsed_declaration)->Contains(origin_) && | 180 if (WhitelistFromDeclaration(parsed_declaration)->Contains(origin_) && |
227 parent_policy->IsFeatureEnabled(feature)) { | 181 parent_policy->IsFeatureEnabled(feature)) { |
228 inherited_policies_[feature] = true; | 182 inherited_policies_[feature] = true; |
229 } else { | 183 } else { |
230 inherited_policies_[feature] = false; | 184 inherited_policies_[feature] = false; |
231 } | 185 } |
232 } | 186 } |
233 } | 187 } |
234 | 188 |
235 // static | 189 // static |
236 const FeaturePolicy::FeatureList& FeaturePolicy::GetDefaultFeatureList() { | 190 const FeaturePolicy::FeatureList& FeaturePolicy::GetDefaultFeatureList() { |
237 CR_DEFINE_STATIC_LOCAL( | 191 CR_DEFINE_STATIC_LOCAL(FeatureList, default_feature_list, |
238 FeatureList, default_feature_list, | 192 ({{blink::WebFeaturePolicyFeature::DocumentCookie, |
239 ({{blink::WebFeaturePolicyFeature::DocumentCookie, &kDocumentCookie}, | 193 FeaturePolicy::FeatureDefault::EnableForAll}, |
240 {blink::WebFeaturePolicyFeature::DocumentDomain, &kDocumentDomain}, | 194 {blink::WebFeaturePolicyFeature::DocumentDomain, |
241 {blink::WebFeaturePolicyFeature::DocumentWrite, &kDocumentWrite}, | 195 FeaturePolicy::FeatureDefault::EnableForAll}, |
242 {blink::WebFeaturePolicyFeature::Fullscreen, &kFullscreenFeature}, | 196 {blink::WebFeaturePolicyFeature::DocumentWrite, |
243 {blink::WebFeaturePolicyFeature::Geolocation, &kGeolocationFeature}, | 197 FeaturePolicy::FeatureDefault::EnableForAll}, |
244 {blink::WebFeaturePolicyFeature::MidiFeature, &kMidiFeature}, | 198 {blink::WebFeaturePolicyFeature::Fullscreen, |
245 {blink::WebFeaturePolicyFeature::Notifications, &kNotificationsFeature}, | 199 FeaturePolicy::FeatureDefault::EnableForSelf}, |
246 {blink::WebFeaturePolicyFeature::Payment, &kPaymentFeature}, | 200 {blink::WebFeaturePolicyFeature::Geolocation, |
247 {blink::WebFeaturePolicyFeature::Push, &kPushFeature}, | 201 FeaturePolicy::FeatureDefault::EnableForSelf}, |
248 {blink::WebFeaturePolicyFeature::SyncScript, &kSyncScript}, | 202 {blink::WebFeaturePolicyFeature::MidiFeature, |
249 {blink::WebFeaturePolicyFeature::SyncXHR, &kSyncXHR}, | 203 FeaturePolicy::FeatureDefault::EnableForAll}, |
250 {blink::WebFeaturePolicyFeature::Usermedia, &kUsermedia}, | 204 {blink::WebFeaturePolicyFeature::Notifications, |
251 {blink::WebFeaturePolicyFeature::Vibrate, &kVibrateFeature}, | 205 FeaturePolicy::FeatureDefault::EnableForAll}, |
252 {blink::WebFeaturePolicyFeature::WebRTC, &kWebRTC}})); | 206 {blink::WebFeaturePolicyFeature::Payment, |
| 207 FeaturePolicy::FeatureDefault::EnableForSelf}, |
| 208 {blink::WebFeaturePolicyFeature::Push, |
| 209 FeaturePolicy::FeatureDefault::EnableForAll}, |
| 210 {blink::WebFeaturePolicyFeature::SyncScript, |
| 211 FeaturePolicy::FeatureDefault::EnableForAll}, |
| 212 {blink::WebFeaturePolicyFeature::SyncXHR, |
| 213 FeaturePolicy::FeatureDefault::EnableForAll}, |
| 214 {blink::WebFeaturePolicyFeature::Usermedia, |
| 215 FeaturePolicy::FeatureDefault::EnableForAll}, |
| 216 {blink::WebFeaturePolicyFeature::Vibrate, |
| 217 FeaturePolicy::FeatureDefault::EnableForSelf}, |
| 218 {blink::WebFeaturePolicyFeature::WebRTC, |
| 219 FeaturePolicy::FeatureDefault::EnableForAll}})); |
253 return default_feature_list; | 220 return default_feature_list; |
254 } | 221 } |
255 | 222 |
256 } // namespace content | 223 } // namespace content |
OLD | NEW |