Chromium Code Reviews| 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); |
|
raymes
2017/03/09 02:52:00
DCHECK_NE(...)
But could this happen in the brows
lunalu1
2017/03/09 16:05:44
Please correct me if I am wrong, to get a ParsedFe
raymes
2017/03/12 23:43:39
ParsedFeaturePolicyHeader is a member of FrameRepl
lunalu1
2017/03/13 15:23:30
Lemme keep DCHECK here for now til most part of fe
| |
| 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}})); | |
|
raymes
2017/03/09 02:52:00
Orhtogonal to this CL: we should think about remov
lunalu1
2017/03/09 16:05:44
Yes. Definitely. After I land in the code to add c
raymes
2017/03/12 23:43:39
Sounds great :)
| |
| 253 return default_feature_list; | 220 return default_feature_list; |
| 254 } | 221 } |
| 255 | 222 |
| 256 } // namespace content | 223 } // namespace content |
| OLD | NEW |