OLD | NEW |
---|---|
(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/RuntimeEnabledFeatures.h" | |
8 #include "testing/gtest/include/gtest/gtest.h" | |
9 | |
10 // Origin strings used for tests | |
11 #define ORIGIN_A "https://example.com/" | |
12 #define ORIGIN_B "https://example.net/" | |
13 #define ORIGIN_C "https://example.org/" | |
14 | |
15 namespace blink { | |
16 | |
17 namespace { | |
18 | |
19 const char* kInvalidPolicies[] = { | |
20 "Not A JSON literal", | |
21 "\"Not a JSON array\"", | |
22 "{\"Also\": \"Not a JSON array\"}", | |
23 "1.0", | |
24 }; | |
25 | |
26 // This is an example of a feature which should be disabled by default, both in | |
27 // top-level and nested frames. | |
28 const FeaturePolicyFeature kOffByDeaultFeature { "offbydefault", false, false }; | |
29 | |
30 } // namespace | |
31 | |
32 class FeaturePolicyTest : public ::testing::Test { | |
33 protected: | |
34 FeaturePolicyTest() | |
35 : m_frameworkWasEnabled(RuntimeEnabledFeatures::featurePolicyEnabled()) | |
36 { | |
37 RuntimeEnabledFeatures::setFeaturePolicyEnabled(true); | |
38 } | |
39 | |
40 ~FeaturePolicyTest() | |
41 { | |
42 RuntimeEnabledFeatures::setFeaturePolicyEnabled(m_frameworkWasEnabled); | |
43 } | |
44 | |
45 RefPtr<SecurityOrigin> originA = SecurityOrigin::createFromString(ORIGIN_A); | |
46 RefPtr<SecurityOrigin> originB = SecurityOrigin::createFromString(ORIGIN_B); | |
47 RefPtr<SecurityOrigin> originC = SecurityOrigin::createFromString(ORIGIN_C); | |
48 | |
49 private: | |
50 const bool m_frameworkWasEnabled; | |
51 }; | |
52 | |
53 TEST_F(FeaturePolicyTest, ParseInvalidPolicy) | |
54 { | |
55 for (const char* invalidPolicy : kInvalidPolicies) { | |
56 EXPECT_TRUE(invalidPolicy); | |
57 } | |
58 } | |
59 | |
60 TEST_F(FeaturePolicyTest, TestInitialPolicy) | |
61 { | |
62 // +-------------+ | |
63 // |(1)Origin A | | |
64 // |No Policy | | |
65 // +-------------+ | |
raymes
2016/09/19 09:19:05
+1 thanks for these awesome diagrams!
| |
66 // Default-on and top-level-only features should be enabled in top-level | |
67 // frame. Default-off features should be disabled. | |
68 FeaturePolicy* policy1 = FeaturePolicy::createFromParentPolicy(nullptr, orig inA); | |
69 EXPECT_TRUE(policy1->isFeatureEnabled(&kDocumentWrite)); | |
70 EXPECT_TRUE(policy1->isFeatureEnabled(&kVibrate)); | |
71 EXPECT_FALSE(policy1->isFeatureEnabled(&kOffByDeaultFeature)); | |
72 } | |
73 | |
74 TEST_F(FeaturePolicyTest, TestInitialChildPolicy) | |
75 { | |
76 // +-----------------+ | |
77 // |(1)Origin A | | |
78 // |No Policy | | |
79 // | +-------------+ | | |
80 // | |(2)Origin A | | | |
81 // | |No Policy | | | |
82 // | +-------------+ | | |
83 // +-----------------+ | |
84 // Default-on features should be enabled in child frame. Default-off and | |
85 // top-level-only features should be disabled. | |
86 FeaturePolicy* policy1 = FeaturePolicy::createFromParentPolicy(nullptr, orig inA); | |
87 FeaturePolicy* policy2 = FeaturePolicy::createFromParentPolicy(policy1, orig inA); | |
88 EXPECT_TRUE(policy2->isFeatureEnabled(&kDocumentWrite)); | |
89 EXPECT_FALSE(policy2->isFeatureEnabled(&kVibrate)); | |
90 EXPECT_FALSE(policy2->isFeatureEnabled(&kOffByDeaultFeature)); | |
91 } | |
92 | |
93 TEST_F(FeaturePolicyTest, TestFrameSelfInheritance) | |
94 { | |
95 // +------------------------------------------+ | |
96 // |(1) Origin A | | |
97 // |Policy: [{"vibrate": ["self"]}] | | |
98 // | +-----------------+ +-----------------+ | | |
99 // | |(2) Origin A | |(4) Origin B | | | |
100 // | |No Policy | |No Policy | | | |
101 // | | +-------------+ | | +-------------+ | | | |
102 // | | |(3)Origin A | | | |(5)Origin B | | | | |
103 // | | |No Policy | | | |No Policy | | | | |
104 // | | +-------------+ | | +-------------+ | | | |
105 // | +-----------------+ +-----------------+ | | |
106 // +------------------------------------------+ | |
107 // Feature should be enabled at the top-level, and through the chain of | |
108 // same-origin frames 2 and 3. It should be disabled in frames 4 and 5, as | |
109 // they are at a different origin. | |
110 FeaturePolicy* policy1 = FeaturePolicy::createFromParentPolicy(nullptr, orig inA); | |
111 policy1->addPolicyFromString("[{\"vibrate\": [\"self\"]}]"); | |
112 FeaturePolicy* policy2 = FeaturePolicy::createFromParentPolicy(policy1, orig inA); | |
113 FeaturePolicy* policy3 = FeaturePolicy::createFromParentPolicy(policy2, orig inA); | |
114 FeaturePolicy* policy4 = FeaturePolicy::createFromParentPolicy(policy1, orig inB); | |
115 FeaturePolicy* policy5 = FeaturePolicy::createFromParentPolicy(policy4, orig inB); | |
116 EXPECT_TRUE(policy2->isFeatureEnabled(&kVibrate)); | |
117 EXPECT_TRUE(policy3->isFeatureEnabled(&kVibrate)); | |
118 EXPECT_FALSE(policy4->isFeatureEnabled(&kVibrate)); | |
119 EXPECT_FALSE(policy5->isFeatureEnabled(&kVibrate)); | |
120 } | |
121 | |
122 TEST_F(FeaturePolicyTest, TestReflexiveFrameSelfInheritance) | |
123 { | |
124 // +---------------------------------+ | |
125 // |(1) Origin A | | |
126 // |Policy: [{"vibrate": ["self"]}] | | |
127 // | +-----------------+ | | |
128 // | |(2) Origin B | | | |
129 // | |No Policy | | | |
130 // | | +-------------+ | | | |
131 // | | |(3)Origin A | | | | |
132 // | | |No Policy | | | | |
133 // | | +-------------+ | | | |
134 // | +-----------------+ | | |
135 // +---------------------------------+ | |
136 // Feature which is enabled at top-level should be disabled in frame 3, as | |
137 // it is embedded by frame 2, for which the feature is not enabled. | |
138 FeaturePolicy* policy1 = FeaturePolicy::createFromParentPolicy(nullptr, orig inA); | |
139 policy1->addPolicyFromString("[{\"vibrate\": [\"self\"]}]"); | |
140 FeaturePolicy* policy2 = FeaturePolicy::createFromParentPolicy(policy1, orig inB); | |
141 FeaturePolicy* policy3 = FeaturePolicy::createFromParentPolicy(policy2, orig inA); | |
142 EXPECT_FALSE(policy2->isFeatureEnabled(&kVibrate)); | |
143 EXPECT_FALSE(policy3->isFeatureEnabled(&kVibrate)); | |
144 } | |
145 | |
146 TEST_F(FeaturePolicyTest, TestSelectiveFrameInheritance) | |
147 { | |
148 // +------------------------------------------+ | |
149 // |(1) Origin A | | |
150 // |Policy: [{"vibrate": ["Origin B"]}] | | |
151 // | +-----------------+ +-----------------+ | | |
152 // | |(2) Origin B | |(3) Origin C | | | |
153 // | |No Policy | |No Policy | | | |
154 // | | | | +-------------+ | | | |
155 // | | | | |(4)Origin B | | | | |
156 // | | | | |No Policy | | | | |
157 // | | | | +-------------+ | | | |
158 // | +-----------------+ +-----------------+ | | |
159 // +------------------------------------------+ | |
160 // Feature should be enabled in second level Origin B frame, but disabled in | |
161 // Frame 4, because it is embedded by frame 3, where the feature is not | |
162 // enabled. | |
163 FeaturePolicy* policy1 = FeaturePolicy::createFromParentPolicy(nullptr, orig inA); | |
164 policy1->addPolicyFromString("[{\"vibrate\": [\"" ORIGIN_B "\"]}]"); | |
165 FeaturePolicy* policy2 = FeaturePolicy::createFromParentPolicy(policy1, orig inB); | |
166 FeaturePolicy* policy3 = FeaturePolicy::createFromParentPolicy(policy1, orig inC); | |
167 FeaturePolicy* policy4 = FeaturePolicy::createFromParentPolicy(policy3, orig inB); | |
168 EXPECT_TRUE(policy2->isFeatureEnabled(&kVibrate)); | |
169 EXPECT_FALSE(policy3->isFeatureEnabled(&kVibrate)); | |
170 EXPECT_FALSE(policy4->isFeatureEnabled(&kVibrate)); | |
171 } | |
172 | |
173 TEST_F(FeaturePolicyTest, TestPolicyCanBlockSelf) | |
174 { | |
175 // +----------------------------+ | |
176 // |(1)Origin A | | |
177 // |Policy: [{"docwrite": []}] | | |
178 // +----------------------------+ | |
179 // Default-on feature should be disabled in top-level frame. | |
180 FeaturePolicy* policy1 = FeaturePolicy::createFromParentPolicy(nullptr, orig inA); | |
181 policy1->addPolicyFromString("[{\"docwrite\": []}]"); | |
182 EXPECT_FALSE(policy1->isFeatureEnabled(&kDocumentWrite)); | |
183 } | |
184 | |
185 TEST_F(FeaturePolicyTest, TestParentPolicyBlocksSameOriginChildPolicy) | |
186 { | |
187 // +----------------------------+ | |
188 // |(1)Origin A | | |
189 // |Policy: [{"docwrite": []}] | | |
190 // | +-------------+ | | |
191 // | |(2)Origin A | | | |
192 // | |No Policy | | | |
193 // | +-------------+ | | |
194 // +----------------------------+ | |
195 // Feature should be disabled in child frame. | |
196 FeaturePolicy* policy1 = FeaturePolicy::createFromParentPolicy(nullptr, orig inA); | |
197 policy1->addPolicyFromString("[{\"docwrite\": []}]"); | |
198 FeaturePolicy* policy2 = FeaturePolicy::createFromParentPolicy(policy1, orig inA); | |
199 EXPECT_FALSE(policy2->isFeatureEnabled(&kDocumentWrite)); | |
200 } | |
201 | |
202 TEST_F(FeaturePolicyTest, TestChildPolicyCanBlockSelf) | |
203 { | |
204 // +--------------------------------+ | |
205 // |(1)Origin A | | |
206 // |No Policy | | |
207 // | +----------------------------+ | | |
208 // | |(2)Origin B | | | |
209 // | |Policy: [{"docwrite": []}] | | | |
210 // | +----------------------------+ | | |
211 // +--------------------------------+ | |
212 // Default-on feature should be disabled by cross-origin child frame. | |
213 FeaturePolicy* policy1 = FeaturePolicy::createFromParentPolicy(nullptr, orig inA); | |
214 FeaturePolicy* policy2 = FeaturePolicy::createFromParentPolicy(policy1, orig inB); | |
215 policy2->addPolicyFromString("[{\"docwrite\": []}]"); | |
216 EXPECT_FALSE(policy2->isFeatureEnabled(&kDocumentWrite)); | |
217 } | |
218 | |
219 TEST_F(FeaturePolicyTest, TestChildPolicyCanBlockChildren) | |
220 { | |
221 // +--------------------------------------+ | |
222 // |(1)Origin A | | |
223 // |No Policy | | |
224 // | +----------------------------------+ | | |
225 // | |(2)Origin B | | | |
226 // | |Policy: [{"docwrite": ["self"]}] | | | |
227 // | | +-------------+ | | | |
228 // | | |(3)Origin C | | | | |
229 // | | |No Policy | | | | |
230 // | | +-------------+ | | | |
231 // | +----------------------------------+ | | |
232 // +--------------------------------------+ | |
233 // Default-on feature should be enabled in frames 1 and 2; disabled in frame | |
234 // 3 by child frame policy. | |
235 FeaturePolicy* policy1 = FeaturePolicy::createFromParentPolicy(nullptr, orig inA); | |
236 FeaturePolicy* policy2 = FeaturePolicy::createFromParentPolicy(policy1, orig inB); | |
237 policy2->addPolicyFromString("[{\"docwrite\": [\"self\"]}]"); | |
238 FeaturePolicy* policy3 = FeaturePolicy::createFromParentPolicy(policy2, orig inC); | |
239 EXPECT_TRUE(policy2->isFeatureEnabled(&kDocumentWrite)); | |
240 EXPECT_FALSE(policy3->isFeatureEnabled(&kDocumentWrite)); | |
241 } | |
242 | |
243 TEST_F(FeaturePolicyTest, TestParentPolicyBlocksCrossOriginChildPolicy) | |
244 { | |
245 // +----------------------------+ | |
246 // |(1)Origin A | | |
247 // |Policy: [{"docwrite": []}] | | |
248 // | +-------------+ | | |
249 // | |(2)Origin B | | | |
250 // | |No Policy | | | |
251 // | +-------------+ | | |
252 // +----------------------------+ | |
253 // Default-on feature should be disabled in cross-origin child frame. | |
254 FeaturePolicy* policy1 = FeaturePolicy::createFromParentPolicy(nullptr, orig inA); | |
255 policy1->addPolicyFromString("[{\"docwrite\": []}]"); | |
256 FeaturePolicy* policy2 = FeaturePolicy::createFromParentPolicy(policy1, orig inB); | |
257 EXPECT_FALSE(policy2->isFeatureEnabled(&kDocumentWrite)); | |
258 } | |
259 | |
260 TEST_F(FeaturePolicyTest, TestEnableForAllOrigins) | |
261 { | |
262 // +------------------------------+ | |
263 // |(1) Origin A | | |
264 // |Policy: [{"vibrate": ["*"]}] | | |
265 // | +-----------------+ | | |
266 // | |(2) Origin B | | | |
267 // | |No Policy | | | |
268 // | | +-------------+ | | | |
269 // | | |(3)Origin A | | | | |
270 // | | |No Policy | | | | |
271 // | | +-------------+ | | | |
272 // | +-----------------+ | | |
273 // +------------------------------+ | |
274 // Feature should be enabled in top and second level; disabled in frame 3. | |
275 FeaturePolicy* policy1 = FeaturePolicy::createFromParentPolicy(nullptr, orig inA); | |
276 policy1->addPolicyFromString("[{\"vibrate\": [\"*\"]}]"); | |
277 FeaturePolicy* policy2 = FeaturePolicy::createFromParentPolicy(policy1, orig inB); | |
278 FeaturePolicy* policy3 = FeaturePolicy::createFromParentPolicy(policy2, orig inA); | |
279 EXPECT_TRUE(policy1->isFeatureEnabled(&kVibrate)); | |
280 EXPECT_TRUE(policy2->isFeatureEnabled(&kVibrate)); | |
281 EXPECT_FALSE(policy3->isFeatureEnabled(&kVibrate)); | |
282 } | |
283 | |
284 TEST_F(FeaturePolicyTest, TestReenableForAllOrigins) | |
285 { | |
286 // +----------------------------------+ | |
287 // |(1) Origin A | | |
288 // |Policy: [{"vibrate": ["*"]}] | | |
289 // | +------------------------------+ | | |
290 // | |(2) Origin B | | | |
291 // | |Policy: [{"vibrate": ["*"]}] | | | |
292 // | | +-------------+ | | | |
293 // | | |(3)Origin A | | | | |
294 // | | |No Policy | | | | |
295 // | | +-------------+ | | | |
296 // | +------------------------------+ | | |
297 // +----------------------------------+ | |
298 // Feature should be enabled in all frames. | |
299 FeaturePolicy* policy1 = FeaturePolicy::createFromParentPolicy(nullptr, orig inA); | |
300 policy1->addPolicyFromString("[{\"vibrate\": [\"*\"]}]"); | |
301 FeaturePolicy* policy2 = FeaturePolicy::createFromParentPolicy(policy1, orig inB); | |
302 policy2->addPolicyFromString("[{\"vibrate\": [\"*\"]}]"); | |
303 FeaturePolicy* policy3 = FeaturePolicy::createFromParentPolicy(policy2, orig inA); | |
304 EXPECT_TRUE(policy1->isFeatureEnabled(&kVibrate)); | |
305 EXPECT_TRUE(policy2->isFeatureEnabled(&kVibrate)); | |
306 EXPECT_TRUE(policy3->isFeatureEnabled(&kVibrate)); | |
307 } | |
308 | |
309 TEST_F(FeaturePolicyTest, TestBlockedFrameCannotReenable) | |
310 { | |
311 // +--------------------------------------+ | |
312 // |(1)Origin A | | |
313 // |Policy: [{"vibrate": ["self"]}] | | |
314 // | +----------------------------------+ | | |
315 // | |(2)Origin B | | | |
316 // | |Policy: [{"vibrate": ["*"]}] | | | |
317 // | | +-------------+ +-------------+ | | | |
318 // | | |(3)Origin A | |(4)Origin C | | | | |
319 // | | |No Policy | |No Policy | | | | |
320 // | | +-------------+ +-------------+ | | | |
321 // | +----------------------------------+ | | |
322 // +--------------------------------------+ | |
323 // Feature should be enabled at the top level; disabled in all other frames. | |
324 FeaturePolicy* policy1 = FeaturePolicy::createFromParentPolicy(nullptr, orig inA); | |
325 policy1->addPolicyFromString("[{\"vibrate\": [\"self\"]}]"); | |
326 FeaturePolicy* policy2 = FeaturePolicy::createFromParentPolicy(policy1, orig inB); | |
327 policy2->addPolicyFromString("[{\"vibrate\": [\"*\"]}]"); | |
328 FeaturePolicy* policy3 = FeaturePolicy::createFromParentPolicy(policy2, orig inA); | |
329 FeaturePolicy* policy4 = FeaturePolicy::createFromParentPolicy(policy2, orig inC); | |
330 EXPECT_TRUE(policy1->isFeatureEnabled(&kVibrate)); | |
331 EXPECT_FALSE(policy2->isFeatureEnabled(&kVibrate)); | |
332 EXPECT_FALSE(policy3->isFeatureEnabled(&kVibrate)); | |
333 EXPECT_FALSE(policy4->isFeatureEnabled(&kVibrate)); | |
334 } | |
335 | |
336 TEST_F(FeaturePolicyTest, TestEnabledFrameCanDelegate) | |
337 { | |
338 // +-------------------------------------------------+ | |
339 // |(1) Origin A | | |
340 // |Policy: [{"vibrate": ["self", "Origin B"]}] | | |
341 // | +---------------------------------------------+ | | |
342 // | |(2) Origin B | | | |
343 // | |Policy: [{"vibrate": ["self", "Origin C"]}] | | | |
344 // | | +-------------+ | | | |
345 // | | |(3)Origin C | | | | |
346 // | | |No Policy | | | | |
347 // | | +-------------+ | | | |
348 // | +---------------------------------------------+ | | |
349 // +-------------------------------------------------+ | |
350 // Feature should be enabled in all frames. | |
351 FeaturePolicy* policy1 = FeaturePolicy::createFromParentPolicy(nullptr, orig inA); | |
352 policy1->addPolicyFromString("[{\"vibrate\": [\"self\", \"" ORIGIN_B "\"]}]" ); | |
353 FeaturePolicy* policy2 = FeaturePolicy::createFromParentPolicy(policy1, orig inB); | |
354 policy2->addPolicyFromString("[{\"vibrate\": [\"self\", \"" ORIGIN_C "\"]}]" ); | |
355 FeaturePolicy* policy3 = FeaturePolicy::createFromParentPolicy(policy2, orig inC); | |
356 EXPECT_TRUE(policy1->isFeatureEnabled(&kVibrate)); | |
357 EXPECT_TRUE(policy2->isFeatureEnabled(&kVibrate)); | |
358 EXPECT_TRUE(policy3->isFeatureEnabled(&kVibrate)); | |
359 } | |
360 | |
361 TEST_F(FeaturePolicyTest, TestFeaturesAreIndependent) | |
362 { | |
363 // +---------------------------------------------+ | |
364 // |(1) Origin A | | |
365 // |Policy: [{"vibrate": ["self", "Origin B"]}, | | |
366 // | {"docwrite": ["self"]}] | | |
367 // | +-----------------------------------------+ | | |
368 // | |(2) Origin B | | | |
369 // | |Policy: [{"vibrate": ["*"], | | | |
370 // | | {"docwrite": ["*"]}] | | | |
371 // | | +-------------+ | | | |
372 // | | |(3)Origin C | | | | |
373 // | | |No Policy | | | | |
374 // | | +-------------+ | | | |
375 // | +-----------------------------------------+ | | |
376 // +---------------------------------------------+ | |
377 // Vibrate feature should be enabled in all frames; Docwrite features should | |
378 // be enabled in frame 1, and disabled in frames 2 and 3. | |
379 FeaturePolicy* policy1 = FeaturePolicy::createFromParentPolicy(nullptr, orig inA); | |
380 policy1->addPolicyFromString("[{\"vibrate\": [\"self\", \"" ORIGIN_B "\"]}, {\"docwrite\": [\"self\"]}]"); | |
381 FeaturePolicy* policy2 = FeaturePolicy::createFromParentPolicy(policy1, orig inB); | |
382 policy2->addPolicyFromString("[{\"vibrate\": [\"*\"]}, {\"docwrite\": [\"*\" ]}]"); | |
383 FeaturePolicy* policy3 = FeaturePolicy::createFromParentPolicy(policy2, orig inC); | |
384 EXPECT_TRUE(policy1->isFeatureEnabled(&kVibrate)); | |
385 EXPECT_TRUE(policy1->isFeatureEnabled(&kDocumentWrite)); | |
386 EXPECT_TRUE(policy2->isFeatureEnabled(&kVibrate)); | |
387 EXPECT_FALSE(policy2->isFeatureEnabled(&kDocumentWrite)); | |
388 EXPECT_TRUE(policy3->isFeatureEnabled(&kVibrate)); | |
389 EXPECT_FALSE(policy3->isFeatureEnabled(&kDocumentWrite)); | |
390 } | |
391 | |
392 } // namespace blink | |
OLD | NEW |