Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(458)

Side by Side Diff: third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp

Issue 2254533002: [FeaturePolicy] Initial implementation of Feature Policy (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fp-flag
Patch Set: Remove overaggressive bool transform Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "platform/feature_policy/FeaturePolicy.h"
6
7 #include "platform/json/JSONParser.h"
8 #include "platform/json/JSONValues.h"
9 #include "platform/weborigin/KURL.h"
10 #include "platform/weborigin/SecurityOrigin.h"
11 #include "wtf/text/StringBuilder.h"
12 #include <algorithm>
13
14 namespace blink {
15
16 namespace {
17
18 const FeaturePolicyFeature* featureForName(const String& featureName)
19 {
20 // TODO: Use make_token_matcher.py to generate this code.
21 if (featureName == "cookie")
22 return &kDocumentCookie;
23 if (featureName == "domain")
24 return &kDocumentDomain;
25 if (featureName == "docwrite")
26 return &kDocumentWrite;
27 if (featureName == "vibrate")
28 return &kVibrate;
29 if (featureName == "webrtc")
30 return &kWebRTC;
31 return &kNoSuchFeature;
32 }
33
34 } // namespace
35
36 const FeaturePolicyFeature kDocumentCookie { "cookie", true, true };
37 const FeaturePolicyFeature kDocumentDomain { "domain", true, true };
38 const FeaturePolicyFeature kDocumentWrite { "docwrite", true, true };
39 const FeaturePolicyFeature kVibrate { "vibrate", true, false };
40 const FeaturePolicyFeature kWebRTC { "webrtc", true, true };
41 const FeaturePolicyFeature kNoSuchFeature { "", false, false };
42
43 FeaturePolicy::Whitelist::Whitelist()
44 : m_matchesAllOrigins(false)
45 {
46 }
47
48 void FeaturePolicy::Whitelist::addAll()
49 {
50 m_matchesAllOrigins = true;
51 }
52
53 void FeaturePolicy::Whitelist::add(RefPtr<SecurityOrigin> origin)
54 {
55 origins.append(origin);
56 }
57
58 bool FeaturePolicy::Whitelist::targets(const SecurityOrigin* origin) const
raymes 2016/09/19 09:19:05 nit: would "contains" be slightly clearer?
iclelland 2016/09/27 15:06:27 Probably; I was using the nomenclature from the or
iclelland 2016/10/14 19:37:49 Done.
59 {
60 if (m_matchesAllOrigins)
61 return true;
62 return (std::any_of(origins.begin(), origins.end(),
63 [origin](const RefPtr<SecurityOrigin>& target)
64 {
65 return target->isSameSchemeHostPortAndSuborigin(origin);
66 }));
raymes 2016/09/19 09:19:04 (optionally) the long-hand way isn't much longer f
iclelland 2016/09/27 15:06:27 Thanks, that's clearer. (I always have such high h
67 }
68
69 // static
70 FeaturePolicy* FeaturePolicy::createFromParentPolicy(const FeaturePolicy* parent , RefPtr<SecurityOrigin> currentOrigin)
71 {
72 FeaturePolicy* newPolicy = new FeaturePolicy(currentOrigin, !parent);
73 if (parent) {
74 for (const auto& item : parent->m_whitelists) {
75 Whitelist newWhitelist;
76 if (item.value.targets(currentOrigin.get())) {
77 newWhitelist.add(currentOrigin);
78 }
79 newPolicy->m_whitelists.set(item.key, newWhitelist);
80 }
81 }
82 return newPolicy;
83 }
84
85 void FeaturePolicy::addPolicyFromString(const String& policy)
raymes 2016/09/19 09:19:04 I think it's a little unclear what it means to "ad
iclelland 2016/09/27 15:06:28 I wouldn't want to pass in the current frame's str
86 {
87 if (policy.isEmpty())
88 return;
89 for (const auto& whitelist : parse(policy)) {
90 if (isFeatureEnabled(whitelist.key)) {
91 m_whitelists.set(whitelist.key, whitelist.value);
92 }
raymes 2016/09/19 09:19:05 Hmm, what about the case where the parent sets "do
iclelland 2016/09/27 15:06:27 No, I think you're right, and I didn't catch that
raymes 2016/09/29 07:17:00 Hmm, I'm still not sure I feel comfortable with th
iclelland 2016/09/30 15:39:26 Sounds like a good idea. I'll see if I can find so
93 }
94 }
95
96 bool FeaturePolicy::isFeatureEnabledForOrigin(const FeaturePolicyFeature* featur e, const SecurityOrigin* origin)
97 {
98 if (m_whitelists.contains(feature)) {
99 const Whitelist& whitelist = m_whitelists.get(feature);
100 return whitelist.targets(origin);
101 }
102 return isFeatureEnabledByDefault(feature, m_isTopLevel);
103 }
104
105 bool FeaturePolicy::isFeatureEnabled(const FeaturePolicyFeature* feature)
106 {
107 return isFeatureEnabledForOrigin(feature, m_origin.get());
108 }
109
110 // static
111 bool FeaturePolicy::isFeatureEnabledByDefault(const FeaturePolicyFeature* featur e, bool isTopLevel)
112 {
113 if (isTopLevel)
114 return feature->enabledByDefault;
115 return feature->enabledInNestedContext;
116 }
117
118 void FeaturePolicy::setFeaturePolicyBindingsInstalled()
119 {
120 m_bindingsInstalled = true;
121 }
122
123 bool FeaturePolicy::featurePolicyBindingsInstalled()
124 {
125 return m_bindingsInstalled;
126 }
127
128 FeaturePolicy::FeaturePolicy(PassRefPtr<SecurityOrigin> currentOrigin, bool isTo pLevel)
129 : m_origin(currentOrigin)
130 , m_isTopLevel(isTopLevel)
131 {
132 }
133
134 HashMap<const FeaturePolicyFeature*, FeaturePolicy::Whitelist>
135 FeaturePolicy::parse(const String& policy)
136 {
137 HashMap<const FeaturePolicyFeature*, Whitelist> whitelists;
138 std::unique_ptr<JSONValue> policyJSON = parseJSON(policy);
139
140 if (!policyJSON)
141 return whitelists;
142
143 std::unique_ptr<JSONArray> items = JSONArray::cast(std::move(policyJSON));
144 if (!items)
145 return whitelists;
146
147 for (size_t i = 0; i < items->size(); ++i) {
148 JSONObject* item = JSONObject::cast(items->at(i));
149 if (!item)
150 continue;
151
152 for (size_t j = 0; j < item->size(); ++j) {
153 JSONObject::Entry entry = item->at(j);
154 String featureName = entry.first;
155 const FeaturePolicyFeature* feature = featureForName(featureName);
156 if (feature != &kNoSuchFeature) {
157 JSONArray* targets = JSONArray::cast(entry.second);
158 if (targets) {
159 Whitelist whitelist;
160 String targetString;
161 for (size_t j = 0; j < targets->size(); ++j) {
162 if (targets->at(j)->asString(&targetString)) {
163 if (equalIgnoringCase(targetString, "self")) {
164 whitelist.add(m_origin);
165 } else if (targetString == "*") {
166 whitelist.addAll();
167 } else {
168 KURL originUrl = KURL(KURL(), targetString);
169 if (originUrl.isValid()) {
170 whitelist.add(SecurityOrigin::create(originU rl));
171 }
172 }
173 }
174 }
175 whitelists.set(feature, whitelist);
176 }
177 } else {
178 continue; // Not a string or an array; invalid policy spec.
179 }
180 }
181 }
182 return whitelists;
raymes 2016/09/19 09:19:05 I haven't reviewed the parsing yet :)
iclelland 2016/09/27 15:06:28 NP; I haven't written a fuzzer for it yet either :
iclelland 2016/10/14 19:37:49 https://codereview.chromium.org/2420013004 FYI
183 }
184
185 DEFINE_TRACE(FeaturePolicy)
186 {
187 }
188
189 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698