Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/security/test/gtest/TestCSPParser.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "gtest/gtest.h"
8
9
#include <string.h>
10
#include <stdlib.h>
11
12
#include "nsIContentSecurityPolicy.h"
13
#include "nsNetUtil.h"
14
#include "mozilla/dom/nsCSPContext.h"
15
#include "nsIPrefService.h"
16
#include "nsIPrefBranch.h"
17
#include "nsStringFwd.h"
18
19
/*
20
 * Testing the parser is non trivial, especially since we can not call
21
 * parser functionality directly in compiled code tests.
22
 * All the tests (except the fuzzy tests at the end) follow the same schemata:
23
 *   a) create an nsIContentSecurityPolicy object
24
 *   b) set the selfURI in SetRequestContext
25
 *   c) append one or more policies by calling AppendPolicy
26
 *   d) check if the policy count is correct by calling GetPolicyCount
27
 *   e) compare the result of the policy with the expected output
28
 *      using the struct PolicyTest;
29
 *
30
 * In general we test:
31
 * a) policies that the parser should accept
32
 * b) policies that the parser should reject
33
 * c) policies that are randomly generated (fuzzy tests)
34
 *
35
 * Please note that fuzzy tests are *DISABLED* by default and shold only
36
 * be run *OFFLINE* whenever code in nsCSPParser changes.
37
 * To run fuzzy tests, flip RUN_OFFLINE_TESTS to 1.
38
 *
39
 */
40
41
#define RUN_OFFLINE_TESTS 0
42
43
/*
44
 * Offline tests are separated in three different groups:
45
 *  * TestFuzzyPolicies - complete random ASCII input
46
 *  * TestFuzzyPoliciesIncDir - a directory name followed by random ASCII
47
 *  * TestFuzzyPoliciesIncDirLimASCII - a directory name followed by limited ASCII
48
 *    which represents more likely user input.
49
 *
50
 *  We run each of this categories |kFuzzyRuns| times.
51
 */
52
53
#if RUN_OFFLINE_TESTS
54
static const uint32_t kFuzzyRuns = 10000;
55
#endif
56
57
// For fuzzy testing we actually do not care about the output,
58
// we just want to make sure that the parser can handle random
59
// input, therefore we use kFuzzyExpectedPolicyCount to return early.
60
static const uint32_t kFuzzyExpectedPolicyCount = 111;
61
62
static const uint32_t kMaxPolicyLength = 96;
63
64
struct PolicyTest
65
{
66
  char policy[kMaxPolicyLength];
67
  char expectedResult[kMaxPolicyLength];
68
};
69
70
nsresult runTest(uint32_t aExpectedPolicyCount, // this should be 0 for policies which should fail to parse
71
                 const char* aPolicy,
72
0
                 const char* aExpectedResult) {
73
0
74
0
  nsresult rv;
75
0
76
0
  // we init the csp with http://www.selfuri.com
77
0
  nsCOMPtr<nsIURI> selfURI;
78
0
  rv = NS_NewURI(getter_AddRefs(selfURI), "http://www.selfuri.com");
79
0
  NS_ENSURE_SUCCESS(rv, rv);
80
0
81
0
  nsCOMPtr<nsIPrincipal> selfURIPrincipal;
82
0
  mozilla::OriginAttributes attrs;
83
0
  selfURIPrincipal =
84
0
    mozilla::BasePrincipal::CreateCodebasePrincipal(selfURI, attrs);
85
0
  NS_ENSURE_TRUE(selfURIPrincipal, NS_ERROR_FAILURE);
86
0
87
0
  // create a CSP object
88
0
  nsCOMPtr<nsIContentSecurityPolicy> csp =
89
0
    do_CreateInstance(NS_CSPCONTEXT_CONTRACTID, &rv);
90
0
  NS_ENSURE_SUCCESS(rv, rv);
91
0
92
0
  // for testing the parser we only need to set a principal which is needed
93
0
  // to translate the keyword 'self' into an actual URI.
94
0
  rv = csp->SetRequestContext(nullptr, selfURIPrincipal);
95
0
  NS_ENSURE_SUCCESS(rv, rv);
96
0
97
0
  // append a policy
98
0
  nsString policyStr;
99
0
  policyStr.AssignASCII(aPolicy);
100
0
  rv = csp->AppendPolicy(policyStr, false, false);
101
0
  NS_ENSURE_SUCCESS(rv, rv);
102
0
103
0
  // when executing fuzzy tests we do not care about the actual output
104
0
  // of the parser, we just want to make sure that the parser is not crashing.
105
0
  if (aExpectedPolicyCount == kFuzzyExpectedPolicyCount) {
106
0
    return NS_OK;
107
0
  }
108
0
109
0
  // verify that the expected number of policies exists
110
0
  uint32_t actualPolicyCount;
111
0
  rv = csp->GetPolicyCount(&actualPolicyCount);
112
0
  NS_ENSURE_SUCCESS(rv, rv);
113
0
  if (actualPolicyCount != aExpectedPolicyCount) {
114
0
    EXPECT_TRUE(false) <<
115
0
      "Actual policy count not equal to expected policy count (" <<
116
0
      actualPolicyCount << " != " << aExpectedPolicyCount <<
117
0
      ") for policy: " << aPolicy;
118
0
    return NS_ERROR_UNEXPECTED;
119
0
  }
120
0
121
0
  // if the expected policy count is 0, we can return, because
122
0
  // we can not compare any output anyway. Used when parsing
123
0
  // errornous policies.
124
0
  if (aExpectedPolicyCount == 0) {
125
0
    return NS_OK;
126
0
  }
127
0
128
0
  // compare the parsed policy against the expected result
129
0
  nsString parsedPolicyStr;
130
0
  // checking policy at index 0, which is the one what we appended.
131
0
  rv = csp->GetPolicyString(0, parsedPolicyStr);
132
0
  NS_ENSURE_SUCCESS(rv, rv);
133
0
134
0
  if (!NS_ConvertUTF16toUTF8(parsedPolicyStr).EqualsASCII(aExpectedResult)) {
135
0
    EXPECT_TRUE(false) <<
136
0
      "Actual policy does not match expected policy (" <<
137
0
      NS_ConvertUTF16toUTF8(parsedPolicyStr).get() << " != " <<
138
0
      aExpectedResult << ")";
139
0
    return NS_ERROR_UNEXPECTED;
140
0
  }
141
0
142
0
  return NS_OK;
143
0
}
144
145
// ============================= run Tests ========================
146
147
nsresult runTestSuite(const PolicyTest* aPolicies,
148
                      uint32_t aPolicyCount,
149
0
                      uint32_t aExpectedPolicyCount) {
150
0
  nsresult rv;
151
0
  nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
152
0
  bool experimentalEnabledCache = false;
153
0
  bool strictDynamicEnabledCache = false;
154
0
  if (prefs)
155
0
  {
156
0
    prefs->GetBoolPref("security.csp.experimentalEnabled", &experimentalEnabledCache);
157
0
    prefs->SetBoolPref("security.csp.experimentalEnabled", true);
158
0
159
0
    prefs->GetBoolPref("security.csp.enableStrictDynamic", &strictDynamicEnabledCache);
160
0
    prefs->SetBoolPref("security.csp.enableStrictDynamic", true);
161
0
  }
162
0
163
0
  for (uint32_t i = 0; i < aPolicyCount; i++) {
164
0
    rv = runTest(aExpectedPolicyCount, aPolicies[i].policy, aPolicies[i].expectedResult);
165
0
    NS_ENSURE_SUCCESS(rv, rv);
166
0
  }
167
0
168
0
  if (prefs) {
169
0
    prefs->SetBoolPref("security.csp.experimentalEnabled", experimentalEnabledCache);
170
0
    prefs->SetBoolPref("security.csp.enableStrictDynamic", strictDynamicEnabledCache);
171
0
  }
172
0
173
0
  return NS_OK;
174
0
}
175
176
// ============================= TestDirectives ========================
177
178
TEST(CSPParser, Directives)
179
0
{
180
0
  static const PolicyTest policies[] =
181
0
  {
182
0
    { "connect-src xn--mnchen-3ya.de",
183
0
      "connect-src http://xn--mnchen-3ya.de"},
184
0
    { "default-src http://www.example.com",
185
0
      "default-src http://www.example.com" },
186
0
    { "script-src http://www.example.com",
187
0
      "script-src http://www.example.com" },
188
0
    { "object-src http://www.example.com",
189
0
      "object-src http://www.example.com" },
190
0
    { "style-src http://www.example.com",
191
0
      "style-src http://www.example.com" },
192
0
    { "img-src http://www.example.com",
193
0
      "img-src http://www.example.com" },
194
0
    { "media-src http://www.example.com",
195
0
      "media-src http://www.example.com" },
196
0
    { "frame-src http://www.example.com",
197
0
      "frame-src http://www.example.com" },
198
0
    { "font-src http://www.example.com",
199
0
      "font-src http://www.example.com" },
200
0
    { "connect-src http://www.example.com",
201
0
      "connect-src http://www.example.com" },
202
0
    { "report-uri http://www.example.com",
203
0
      "report-uri http://www.example.com/" },
204
0
    { "script-src 'nonce-correctscriptnonce'",
205
0
      "script-src 'nonce-correctscriptnonce'" },
206
0
    { "script-src 'nonce-a'",
207
0
      "script-src 'nonce-a'" },
208
0
    { "script-src 'sha256-a'",
209
0
      "script-src 'sha256-a'" },
210
0
    { "script-src 'sha256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI='",
211
0
      "script-src 'sha256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI='" },
212
0
    { "require-sri-for script style",
213
0
      "require-sri-for script style"},
214
0
    { "script-src 'nonce-foo' 'unsafe-inline' ",
215
0
      "script-src 'nonce-foo' 'unsafe-inline'" },
216
0
    { "script-src 'nonce-foo' 'strict-dynamic' 'unsafe-inline' https:  ",
217
0
      "script-src 'nonce-foo' 'strict-dynamic' 'unsafe-inline' https:" },
218
0
    { "default-src 'sha256-siVR8' 'strict-dynamic' 'unsafe-inline' https:  ",
219
0
      "default-src 'sha256-siVR8' 'unsafe-inline' https:" },
220
0
    { "worker-src https://example.com",
221
0
      "worker-src https://example.com" },
222
0
    { "worker-src http://worker.com; frame-src http://frame.com; child-src http://child.com",
223
0
      "worker-src http://worker.com; frame-src http://frame.com; child-src http://child.com" },
224
0
  };
225
0
226
0
  uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
227
0
  ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)));
228
0
}
229
230
// ============================= TestKeywords ========================
231
232
TEST(CSPParser, Keywords)
233
0
{
234
0
  static const PolicyTest policies[] =
235
0
  {
236
0
    { "script-src 'self'",
237
0
      "script-src 'self'" },
238
0
    { "script-src 'unsafe-inline'",
239
0
      "script-src 'unsafe-inline'" },
240
0
    { "script-src 'unsafe-eval'",
241
0
      "script-src 'unsafe-eval'" },
242
0
    { "script-src 'unsafe-inline' 'unsafe-eval'",
243
0
      "script-src 'unsafe-inline' 'unsafe-eval'" },
244
0
    { "script-src 'none'",
245
0
      "script-src 'none'" },
246
0
    { "img-src 'none'; script-src 'unsafe-eval' 'unsafe-inline'; default-src 'self'",
247
0
      "img-src 'none'; script-src 'unsafe-eval' 'unsafe-inline'; default-src 'self'" },
248
0
  };
249
0
250
0
  uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
251
0
  ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)));
252
0
}
253
254
// ============================= TestIgnoreUpperLowerCasePolicies ========================
255
256
TEST(CSPParser, IgnoreUpperLowerCasePolicies)
257
0
{
258
0
  static const PolicyTest policies[] =
259
0
  {
260
0
    { "script-src 'SELF'",
261
0
      "script-src 'self'" },
262
0
    { "sCriPt-src 'Unsafe-Inline'",
263
0
      "script-src 'unsafe-inline'" },
264
0
    { "SCRIPT-src 'unsafe-eval'",
265
0
      "script-src 'unsafe-eval'" },
266
0
    { "default-SRC 'unsafe-inline' 'unsafe-eval'",
267
0
      "default-src 'unsafe-inline' 'unsafe-eval'" },
268
0
    { "script-src 'NoNe'",
269
0
      "script-src 'none'" },
270
0
    { "img-sRc 'noNe'; scrIpt-src 'unsafe-EVAL' 'UNSAFE-inline'; deFAULT-src 'Self'",
271
0
      "img-src 'none'; script-src 'unsafe-eval' 'unsafe-inline'; default-src 'self'" },
272
0
    { "default-src HTTP://www.example.com",
273
0
      "default-src http://www.example.com" },
274
0
    { "default-src HTTP://WWW.EXAMPLE.COM",
275
0
      "default-src http://www.example.com" },
276
0
    { "default-src HTTPS://*.example.COM",
277
0
      "default-src https://*.example.com" },
278
0
    { "script-src 'none' test.com;",
279
0
      "script-src http://test.com" },
280
0
    { "script-src 'NoNCE-correctscriptnonce'",
281
0
      "script-src 'nonce-correctscriptnonce'" },
282
0
    { "script-src 'NoncE-NONCENEEDSTOBEUPPERCASE'",
283
0
      "script-src 'nonce-NONCENEEDSTOBEUPPERCASE'" },
284
0
    { "script-src 'SHA256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI='",
285
0
      "script-src 'sha256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI='" },
286
0
    { "upgrade-INSECURE-requests",
287
0
      "upgrade-insecure-requests" },
288
0
    { "sanDBox alloW-foRMs",
289
0
      "sandbox allow-forms"},
290
0
    { "require-SRI-for sCript stYle",
291
0
      "require-sri-for script style"},
292
0
  };
293
0
294
0
  uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
295
0
  ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)));
296
0
}
297
298
// ============================= TestPaths ========================
299
300
TEST(CSPParser, Paths)
301
0
{
302
0
  static const PolicyTest policies[] =
303
0
  {
304
0
    { "script-src http://www.example.com",
305
0
      "script-src http://www.example.com" },
306
0
    { "script-src http://www.example.com/",
307
0
      "script-src http://www.example.com/" },
308
0
    { "script-src http://www.example.com/path-1",
309
0
      "script-src http://www.example.com/path-1" },
310
0
    { "script-src http://www.example.com/path-1/",
311
0
      "script-src http://www.example.com/path-1/" },
312
0
    { "script-src http://www.example.com/path-1/path_2",
313
0
      "script-src http://www.example.com/path-1/path_2" },
314
0
    { "script-src http://www.example.com/path-1/path_2/",
315
0
      "script-src http://www.example.com/path-1/path_2/" },
316
0
    { "script-src http://www.example.com/path-1/path_2/file.js",
317
0
      "script-src http://www.example.com/path-1/path_2/file.js" },
318
0
    { "script-src http://www.example.com/path-1/path_2/file_1.js",
319
0
      "script-src http://www.example.com/path-1/path_2/file_1.js" },
320
0
    { "script-src http://www.example.com/path-1/path_2/file-2.js",
321
0
      "script-src http://www.example.com/path-1/path_2/file-2.js" },
322
0
    { "script-src http://www.example.com/path-1/path_2/f.js",
323
0
      "script-src http://www.example.com/path-1/path_2/f.js" },
324
0
    { "script-src http://www.example.com:88",
325
0
      "script-src http://www.example.com:88" },
326
0
    { "script-src http://www.example.com:88/",
327
0
      "script-src http://www.example.com:88/" },
328
0
    { "script-src http://www.example.com:88/path-1",
329
0
      "script-src http://www.example.com:88/path-1" },
330
0
    { "script-src http://www.example.com:88/path-1/",
331
0
      "script-src http://www.example.com:88/path-1/" },
332
0
    { "script-src http://www.example.com:88/path-1/path_2",
333
0
      "script-src http://www.example.com:88/path-1/path_2" },
334
0
    { "script-src http://www.example.com:88/path-1/path_2/",
335
0
      "script-src http://www.example.com:88/path-1/path_2/" },
336
0
    { "script-src http://www.example.com:88/path-1/path_2/file.js",
337
0
      "script-src http://www.example.com:88/path-1/path_2/file.js" },
338
0
    { "script-src http://www.example.com:*",
339
0
      "script-src http://www.example.com:*" },
340
0
    { "script-src http://www.example.com:*/",
341
0
      "script-src http://www.example.com:*/" },
342
0
    { "script-src http://www.example.com:*/path-1",
343
0
      "script-src http://www.example.com:*/path-1" },
344
0
    { "script-src http://www.example.com:*/path-1/",
345
0
      "script-src http://www.example.com:*/path-1/" },
346
0
    { "script-src http://www.example.com:*/path-1/path_2",
347
0
      "script-src http://www.example.com:*/path-1/path_2" },
348
0
    { "script-src http://www.example.com:*/path-1/path_2/",
349
0
      "script-src http://www.example.com:*/path-1/path_2/" },
350
0
    { "script-src http://www.example.com:*/path-1/path_2/file.js",
351
0
      "script-src http://www.example.com:*/path-1/path_2/file.js" },
352
0
    { "script-src http://www.example.com#foo",
353
0
      "script-src http://www.example.com" },
354
0
    { "script-src http://www.example.com?foo=bar",
355
0
      "script-src http://www.example.com" },
356
0
    { "script-src http://www.example.com:8888#foo",
357
0
      "script-src http://www.example.com:8888" },
358
0
    { "script-src http://www.example.com:8888?foo",
359
0
      "script-src http://www.example.com:8888" },
360
0
    { "script-src http://www.example.com/#foo",
361
0
      "script-src http://www.example.com/" },
362
0
    { "script-src http://www.example.com/?foo",
363
0
      "script-src http://www.example.com/" },
364
0
    { "script-src http://www.example.com/path-1/file.js#foo",
365
0
      "script-src http://www.example.com/path-1/file.js" },
366
0
    { "script-src http://www.example.com/path-1/file.js?foo",
367
0
      "script-src http://www.example.com/path-1/file.js" },
368
0
    { "script-src http://www.example.com/path-1/file.js?foo#bar",
369
0
      "script-src http://www.example.com/path-1/file.js" },
370
0
    { "report-uri http://www.example.com/",
371
0
      "report-uri http://www.example.com/" },
372
0
    { "report-uri http://www.example.com:8888/asdf",
373
0
      "report-uri http://www.example.com:8888/asdf" },
374
0
    { "report-uri http://www.example.com:8888/path_1/path_2",
375
0
      "report-uri http://www.example.com:8888/path_1/path_2" },
376
0
    { "report-uri http://www.example.com:8888/path_1/path_2/report.sjs&301",
377
0
      "report-uri http://www.example.com:8888/path_1/path_2/report.sjs&301" },
378
0
    { "report-uri /examplepath",
379
0
      "report-uri http://www.selfuri.com/examplepath" },
380
0
    { "connect-src http://www.example.com/foo%3Bsessionid=12%2C34",
381
0
      "connect-src http://www.example.com/foo;sessionid=12,34" },
382
0
    { "connect-src http://www.example.com/foo%3bsessionid=12%2c34",
383
0
      "connect-src http://www.example.com/foo;sessionid=12,34" },
384
0
    { "connect-src http://test.com/pathIncludingAz19-._~!$&'()*+=:@",
385
0
      "connect-src http://test.com/pathIncludingAz19-._~!$&'()*+=:@" },
386
0
    { "script-src http://www.example.com:88/.js",
387
0
      "script-src http://www.example.com:88/.js" },
388
0
    { "script-src https://foo.com/_abc/abc_/_/_a_b_c_",
389
0
      "script-src https://foo.com/_abc/abc_/_/_a_b_c_" }
390
0
  };
391
0
392
0
  uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
393
0
  ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)));
394
0
}
395
396
// ============================= TestSimplePolicies ========================
397
398
TEST(CSPParser, SimplePolicies)
399
0
{
400
0
  static const PolicyTest policies[] =
401
0
  {
402
0
    { "default-src *",
403
0
      "default-src *" },
404
0
    { "default-src https:",
405
0
      "default-src https:" },
406
0
    { "default-src https://*",
407
0
      "default-src https://*" },
408
0
    { "default-src *:*",
409
0
      "default-src http://*:*" },
410
0
    { "default-src *:80",
411
0
      "default-src http://*:80" },
412
0
    { "default-src http://*:80",
413
0
      "default-src http://*:80" },
414
0
    { "default-src javascript:",
415
0
      "default-src javascript:" },
416
0
    { "default-src data:",
417
0
      "default-src data:" },
418
0
    { "script-src 'unsafe-eval' 'unsafe-inline' http://www.example.com",
419
0
      "script-src 'unsafe-eval' 'unsafe-inline' http://www.example.com" },
420
0
    { "object-src 'self'",
421
0
      "object-src 'self'" },
422
0
    { "style-src http://www.example.com 'self'",
423
0
      "style-src http://www.example.com 'self'" },
424
0
    { "media-src http://www.example.com http://www.test.com",
425
0
      "media-src http://www.example.com http://www.test.com" },
426
0
    { "connect-src http://www.test.com example.com *.other.com;",
427
0
      "connect-src http://www.test.com http://example.com http://*.other.com"},
428
0
    { "connect-src example.com *.other.com",
429
0
      "connect-src http://example.com http://*.other.com"},
430
0
    { "style-src *.other.com example.com",
431
0
      "style-src http://*.other.com http://example.com"},
432
0
    { "default-src 'self'; img-src *;",
433
0
      "default-src 'self'; img-src *" },
434
0
    { "object-src media1.example.com media2.example.com *.cdn.example.com;",
435
0
      "object-src http://media1.example.com http://media2.example.com http://*.cdn.example.com" },
436
0
    { "script-src trustedscripts.example.com",
437
0
      "script-src http://trustedscripts.example.com" },
438
0
    { "script-src 'self' ; default-src trustedscripts.example.com",
439
0
      "script-src 'self'; default-src http://trustedscripts.example.com" },
440
0
    { "default-src 'none'; report-uri http://localhost:49938/test",
441
0
      "default-src 'none'; report-uri http://localhost:49938/test" },
442
0
    { "   ;   default-src abc",
443
0
      "default-src http://abc" },
444
0
    { " ; ; ; ;     default-src            abc    ; ; ; ;",
445
0
      "default-src http://abc" },
446
0
    { "script-src 'none' 'none' 'none';",
447
0
      "script-src 'none'" },
448
0
    { "script-src http://www.example.com/path-1//",
449
0
      "script-src http://www.example.com/path-1//" },
450
0
    { "script-src http://www.example.com/path-1//path_2",
451
0
      "script-src http://www.example.com/path-1//path_2" },
452
0
    { "default-src 127.0.0.1",
453
0
      "default-src http://127.0.0.1" },
454
0
    { "default-src 127.0.0.1:*",
455
0
      "default-src http://127.0.0.1:*" },
456
0
    { "default-src -; ",
457
0
      "default-src http://-" },
458
0
    { "script-src 1",
459
0
      "script-src http://1" },
460
0
    { "upgrade-insecure-requests",
461
0
      "upgrade-insecure-requests" },
462
0
    { "upgrade-insecure-requests https:",
463
0
      "upgrade-insecure-requests" },
464
0
    { "sandbox allow-scripts allow-forms  ",
465
0
      "sandbox allow-scripts allow-forms" },
466
0
  };
467
0
468
0
  uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
469
0
  ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)));
470
0
}
471
472
// ============================= TestPoliciesWithInvalidSrc ========================
473
474
TEST(CSPParser, PoliciesWithInvalidSrc)
475
0
{
476
0
  static const PolicyTest policies[] =
477
0
  {
478
0
    { "script-src 'self'; SCRIPT-SRC http://www.example.com",
479
0
      "script-src 'self'" },
480
0
    { "script-src 'none' test.com; script-src example.com",
481
0
      "script-src http://test.com" },
482
0
    { "default-src **",
483
0
      "default-src 'none'" },
484
0
    { "default-src 'self",
485
0
      "default-src 'none'" },
486
0
    { "default-src 'unsafe-inlin' ",
487
0
      "default-src 'none'" },
488
0
    { "default-src */",
489
0
      "default-src 'none'" },
490
0
    { "default-src",
491
0
      "default-src 'none'" },
492
0
    { "default-src 'unsafe-inlin' ",
493
0
      "default-src 'none'" },
494
0
    { "default-src :88",
495
0
      "default-src 'none'" },
496
0
    { "script-src abc::::::88",
497
0
      "script-src 'none'" },
498
0
    { "script-src *.*:*",
499
0
      "script-src 'none'" },
500
0
    { "img-src *::88",
501
0
      "img-src 'none'" },
502
0
    { "object-src http://localhost:",
503
0
      "object-src 'none'" },
504
0
    { "script-src test..com",
505
0
      "script-src 'none'" },
506
0
    { "script-src sub1.sub2.example+",
507
0
      "script-src 'none'" },
508
0
    { "script-src http://www.example.com//",
509
0
      "script-src 'none'" },
510
0
    { "script-src http://www.example.com:88path-1/",
511
0
      "script-src 'none'" },
512
0
    { "script-src http://www.example.com:88//",
513
0
      "script-src 'none'" },
514
0
    { "script-src http://www.example.com:88//path-1",
515
0
      "script-src 'none'" },
516
0
    { "script-src http://www.example.com:88//path-1",
517
0
      "script-src 'none'" },
518
0
    { "script-src http://www.example.com:88.js",
519
0
      "script-src 'none'" },
520
0
    { "script-src http://www.example.com:*.js",
521
0
      "script-src 'none'" },
522
0
    { "script-src http://www.example.com:*.",
523
0
      "script-src 'none'" },
524
0
    { "script-src 'nonce-{invalid}'",
525
0
      "script-src 'none'" },
526
0
    { "script-src 'sha256-{invalid}'",
527
0
      "script-src 'none'" },
528
0
    { "script-src 'nonce-in$valid'",
529
0
      "script-src 'none'" },
530
0
    { "script-src 'sha256-in$valid'",
531
0
      "script-src 'none'" },
532
0
    { "script-src 'nonce-invalid==='",
533
0
      "script-src 'none'" },
534
0
    { "script-src 'sha256-invalid==='",
535
0
      "script-src 'none'" },
536
0
    { "script-src 'nonce-==='",
537
0
      "script-src 'none'" },
538
0
    { "script-src 'sha256-==='",
539
0
      "script-src 'none'" },
540
0
    { "script-src 'nonce-=='",
541
0
      "script-src 'none'" },
542
0
    { "script-src 'sha256-=='",
543
0
      "script-src 'none'" },
544
0
    { "script-src 'nonce-='",
545
0
      "script-src 'none'" },
546
0
    { "script-src 'sha256-='",
547
0
      "script-src 'none'" },
548
0
    { "script-src 'nonce-'",
549
0
      "script-src 'none'" },
550
0
    { "script-src 'sha256-'",
551
0
      "script-src 'none'" },
552
0
    { "connect-src http://www.example.com/foo%zz;",
553
0
      "connect-src 'none'" },
554
0
    { "script-src https://foo.com/%$",
555
0
      "script-src 'none'" },
556
0
    { "require-SRI-for script elephants",
557
0
      "require-sri-for script"},
558
0
    { "sandbox    foo",
559
0
      "sandbox"},
560
0
  };
561
0
562
0
  // amount of tests - 1, because the latest should be ignored.
563
0
  uint32_t policyCount = (sizeof(policies) / sizeof(PolicyTest)) -1;
564
0
  ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)));
565
0
}
566
567
// ============================= TestBadPolicies ========================
568
569
TEST(CSPParser, BadPolicies)
570
0
{
571
0
  static const PolicyTest policies[] =
572
0
  {
573
0
    { "script-sr 'self", "" },
574
0
    { "", "" },
575
0
    { "; ; ; ; ; ; ;", "" },
576
0
    { "defaut-src asdf", "" },
577
0
    { "default-src: aaa", "" },
578
0
    { "asdf http://test.com", ""},
579
0
    { "require-sri-for", ""},
580
0
    { "require-sri-for foo", ""},
581
0
    { "report-uri", ""},
582
0
    { "report-uri http://:foo", ""},
583
0
  };
584
0
585
0
  uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
586
0
  ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 0)));
587
0
}
588
589
// ============================= TestGoodGeneratedPolicies ========================
590
591
TEST(CSPParser, GoodGeneratedPolicies)
592
0
{
593
0
  static const PolicyTest policies[] =
594
0
  {
595
0
    { "default-src 'self'; img-src *",
596
0
      "default-src 'self'; img-src *" },
597
0
    { "report-uri /policy",
598
0
      "report-uri http://www.selfuri.com/policy"},
599
0
    { "img-src *",
600
0
      "img-src *" },
601
0
    { "media-src foo.bar",
602
0
      "media-src http://foo.bar" },
603
0
    { "frame-src *.bar",
604
0
      "frame-src http://*.bar" },
605
0
    { "font-src com",
606
0
      "font-src http://com" },
607
0
    { "connect-src f00b4r.com",
608
0
      "connect-src http://f00b4r.com" },
609
0
    { "script-src *.a.b.c",
610
0
      "script-src http://*.a.b.c" },
611
0
    { "object-src *.b.c",
612
0
      "object-src http://*.b.c" },
613
0
    { "style-src a.b.c",
614
0
      "style-src http://a.b.c" },
615
0
    { "img-src a.com",
616
0
      "img-src http://a.com" },
617
0
    { "media-src http://abc.com",
618
0
      "media-src http://abc.com" },
619
0
    { "frame-src a2-c.com",
620
0
      "frame-src http://a2-c.com" },
621
0
    { "font-src https://a.com",
622
0
      "font-src https://a.com" },
623
0
    { "connect-src *.a.com",
624
0
      "connect-src http://*.a.com" },
625
0
    { "default-src a.com:23",
626
0
      "default-src http://a.com:23" },
627
0
    { "script-src https://a.com:200",
628
0
      "script-src https://a.com:200" },
629
0
    { "object-src data:",
630
0
      "object-src data:" },
631
0
    { "style-src javascript:",
632
0
      "style-src javascript:" },
633
0
    { "frame-src https://foobar.com:443",
634
0
      "frame-src https://foobar.com:443" },
635
0
    { "font-src https://a.com:443",
636
0
      "font-src https://a.com:443" },
637
0
    { "connect-src http://a.com:80",
638
0
      "connect-src http://a.com:80" },
639
0
    { "default-src http://foobar.com",
640
0
      "default-src http://foobar.com" },
641
0
    { "script-src https://foobar.com",
642
0
      "script-src https://foobar.com" },
643
0
    { "style-src 'none'",
644
0
      "style-src 'none'" },
645
0
    { "img-src foo.bar:21 https://ras.bar",
646
0
      "img-src http://foo.bar:21 https://ras.bar" },
647
0
    { "media-src http://foo.bar:21 https://ras.bar:443",
648
0
      "media-src http://foo.bar:21 https://ras.bar:443" },
649
0
    { "frame-src http://self.com:80",
650
0
      "frame-src http://self.com:80" },
651
0
    { "font-src http://self.com",
652
0
      "font-src http://self.com" },
653
0
    { "connect-src https://foo.com http://bar.com:88",
654
0
      "connect-src https://foo.com http://bar.com:88" },
655
0
    { "default-src * https://bar.com 'none'",
656
0
      "default-src * https://bar.com" },
657
0
    { "script-src *.foo.com",
658
0
      "script-src http://*.foo.com" },
659
0
    { "object-src http://b.com",
660
0
      "object-src http://b.com" },
661
0
    { "style-src http://bar.com:88",
662
0
      "style-src http://bar.com:88" },
663
0
    { "img-src https://bar.com:88",
664
0
      "img-src https://bar.com:88" },
665
0
    { "media-src http://bar.com:443",
666
0
      "media-src http://bar.com:443" },
667
0
    { "frame-src https://foo.com:88",
668
0
      "frame-src https://foo.com:88" },
669
0
    { "font-src http://foo.com",
670
0
      "font-src http://foo.com" },
671
0
    { "connect-src http://x.com:23",
672
0
      "connect-src http://x.com:23" },
673
0
    { "default-src http://barbaz.com",
674
0
      "default-src http://barbaz.com" },
675
0
    { "script-src http://somerandom.foo.com",
676
0
      "script-src http://somerandom.foo.com" },
677
0
    { "default-src *",
678
0
      "default-src *" },
679
0
    { "style-src http://bar.com:22",
680
0
      "style-src http://bar.com:22" },
681
0
    { "img-src https://foo.com:443",
682
0
      "img-src https://foo.com:443" },
683
0
    { "script-src https://foo.com; ",
684
0
      "script-src https://foo.com" },
685
0
    { "img-src bar.com:*",
686
0
      "img-src http://bar.com:*" },
687
0
    { "font-src https://foo.com:400",
688
0
      "font-src https://foo.com:400" },
689
0
    { "connect-src http://bar.com:400",
690
0
      "connect-src http://bar.com:400" },
691
0
    { "default-src http://evil.com",
692
0
      "default-src http://evil.com" },
693
0
    { "script-src https://evil.com:100",
694
0
      "script-src https://evil.com:100" },
695
0
    { "default-src bar.com; script-src https://foo.com",
696
0
      "default-src http://bar.com; script-src https://foo.com" },
697
0
    { "default-src 'self'; script-src 'self' https://*:*",
698
0
      "default-src 'self'; script-src 'self' https://*:*" },
699
0
    { "img-src http://self.com:34",
700
0
      "img-src http://self.com:34" },
701
0
    { "media-src http://subd.self.com:34",
702
0
      "media-src http://subd.self.com:34" },
703
0
    { "default-src 'none'",
704
0
      "default-src 'none'" },
705
0
    { "connect-src http://self",
706
0
      "connect-src http://self" },
707
0
    { "default-src http://foo",
708
0
      "default-src http://foo" },
709
0
    { "script-src http://foo:80",
710
0
      "script-src http://foo:80" },
711
0
    { "object-src http://bar",
712
0
      "object-src http://bar" },
713
0
    { "style-src http://three:80",
714
0
      "style-src http://three:80" },
715
0
    { "img-src https://foo:400",
716
0
      "img-src https://foo:400" },
717
0
    { "media-src https://self:34",
718
0
      "media-src https://self:34" },
719
0
    { "frame-src https://bar",
720
0
      "frame-src https://bar" },
721
0
    { "font-src http://three:81",
722
0
      "font-src http://three:81" },
723
0
    { "connect-src https://three:81",
724
0
      "connect-src https://three:81" },
725
0
    { "script-src http://self.com:80/foo",
726
0
      "script-src http://self.com:80/foo" },
727
0
    { "object-src http://self.com/foo",
728
0
      "object-src http://self.com/foo" },
729
0
    { "report-uri /report.py",
730
0
      "report-uri http://www.selfuri.com/report.py"},
731
0
    { "img-src http://foo.org:34/report.py",
732
0
      "img-src http://foo.org:34/report.py" },
733
0
    { "media-src foo/bar/report.py",
734
0
      "media-src http://foo/bar/report.py" },
735
0
    { "report-uri /",
736
0
      "report-uri http://www.selfuri.com/"},
737
0
    { "font-src https://self.com/report.py",
738
0
      "font-src https://self.com/report.py" },
739
0
    { "connect-src https://foo.com/report.py",
740
0
      "connect-src https://foo.com/report.py" },
741
0
    { "default-src *; report-uri  http://www.reporturi.com/",
742
0
      "default-src *; report-uri http://www.reporturi.com/" },
743
0
    { "default-src http://first.com",
744
0
      "default-src http://first.com" },
745
0
    { "script-src http://second.com",
746
0
      "script-src http://second.com" },
747
0
    { "object-src http://third.com",
748
0
      "object-src http://third.com" },
749
0
    { "style-src https://foobar.com:4443",
750
0
      "style-src https://foobar.com:4443" },
751
0
    { "img-src http://foobar.com:4443",
752
0
      "img-src http://foobar.com:4443" },
753
0
    { "media-src bar.com",
754
0
      "media-src http://bar.com" },
755
0
    { "frame-src http://bar.com",
756
0
      "frame-src http://bar.com" },
757
0
    { "font-src http://self.com/",
758
0
      "font-src http://self.com/" },
759
0
    { "script-src 'self'",
760
0
      "script-src 'self'" },
761
0
    { "default-src http://self.com/foo.png",
762
0
      "default-src http://self.com/foo.png" },
763
0
    { "script-src http://self.com/foo.js",
764
0
      "script-src http://self.com/foo.js" },
765
0
    { "object-src http://bar.com/foo.js",
766
0
      "object-src http://bar.com/foo.js" },
767
0
    { "style-src http://FOO.COM",
768
0
      "style-src http://foo.com" },
769
0
    { "img-src HTTP",
770
0
      "img-src http://http" },
771
0
    { "media-src http",
772
0
      "media-src http://http" },
773
0
    { "frame-src 'SELF'",
774
0
      "frame-src 'self'" },
775
0
    { "DEFAULT-src 'self';",
776
0
      "default-src 'self'" },
777
0
    { "default-src 'self' http://FOO.COM",
778
0
      "default-src 'self' http://foo.com" },
779
0
    { "default-src 'self' HTTP://foo.com",
780
0
      "default-src 'self' http://foo.com" },
781
0
    { "default-src 'NONE'",
782
0
      "default-src 'none'" },
783
0
    { "script-src policy-uri ",
784
0
      "script-src http://policy-uri" },
785
0
    { "img-src 'self'; ",
786
0
      "img-src 'self'" },
787
0
    { "frame-ancestors foo-bar.com",
788
0
      "frame-ancestors http://foo-bar.com" },
789
0
    { "frame-ancestors http://a.com",
790
0
      "frame-ancestors http://a.com" },
791
0
    { "frame-ancestors 'self'",
792
0
      "frame-ancestors 'self'" },
793
0
    { "frame-ancestors http://self.com:88",
794
0
      "frame-ancestors http://self.com:88" },
795
0
    { "frame-ancestors http://a.b.c.d.e.f.g.h.i.j.k.l.x.com",
796
0
      "frame-ancestors http://a.b.c.d.e.f.g.h.i.j.k.l.x.com" },
797
0
    { "frame-ancestors https://self.com:34",
798
0
      "frame-ancestors https://self.com:34" },
799
0
    { "frame-ancestors http://sampleuser:samplepass@example.com",
800
0
      "frame-ancestors 'none'" },
801
0
    { "default-src 'none'; frame-ancestors 'self'",
802
0
      "default-src 'none'; frame-ancestors 'self'" },
803
0
    { "frame-ancestors http://self:80",
804
0
      "frame-ancestors http://self:80" },
805
0
    { "frame-ancestors http://self.com/bar",
806
0
      "frame-ancestors http://self.com/bar" },
807
0
    { "default-src 'self'; frame-ancestors 'self'",
808
0
      "default-src 'self'; frame-ancestors 'self'" },
809
0
    { "frame-ancestors http://bar.com/foo.png",
810
0
      "frame-ancestors http://bar.com/foo.png" },
811
0
  };
812
0
813
0
  uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
814
0
  ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)));
815
0
}
816
817
// ============================= TestBadGeneratedPolicies ========================
818
819
TEST(CSPParser, BadGeneratedPolicies)
820
0
{
821
0
  static const PolicyTest policies[] =
822
0
  {
823
0
    { "foo.*.bar", ""},
824
0
    { "foo!bar.com", ""},
825
0
    { "x.*.a.com", ""},
826
0
    { "a#2-c.com", ""},
827
0
    { "http://foo.com:bar.com:23", ""},
828
0
    { "f!oo.bar", ""},
829
0
    { "ht!ps://f-oo.bar", ""},
830
0
    { "https://f-oo.bar:3f", ""},
831
0
    { "**", ""},
832
0
    { "*a", ""},
833
0
    { "http://username:password@self.com/foo", ""},
834
0
    { "http://other:pass1@self.com/foo", ""},
835
0
    { "http://user1:pass1@self.com/foo", ""},
836
0
    { "http://username:password@self.com/bar", ""},
837
0
  };
838
0
839
0
  uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
840
0
  ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 0)));
841
0
}
842
843
// ============ TestGoodGeneratedPoliciesForPathHandling ============
844
845
TEST(CSPParser, GoodGeneratedPoliciesForPathHandling)
846
0
{
847
0
  // Once bug 808292 (Implement path-level host-source matching to CSP)
848
0
  // lands we have to update the expected output to include the parsed path
849
0
850
0
  static const PolicyTest policies[] =
851
0
  {
852
0
    { "img-src http://test1.example.com",
853
0
      "img-src http://test1.example.com" },
854
0
    { "img-src http://test1.example.com/",
855
0
      "img-src http://test1.example.com/" },
856
0
    { "img-src http://test1.example.com/path-1",
857
0
      "img-src http://test1.example.com/path-1" },
858
0
    { "img-src http://test1.example.com/path-1/",
859
0
      "img-src http://test1.example.com/path-1/" },
860
0
    { "img-src http://test1.example.com/path-1/path_2/",
861
0
      "img-src http://test1.example.com/path-1/path_2/" },
862
0
    { "img-src http://test1.example.com/path-1/path_2/file.js",
863
0
      "img-src http://test1.example.com/path-1/path_2/file.js" },
864
0
    { "img-src http://test1.example.com/path-1/path_2/file_1.js",
865
0
      "img-src http://test1.example.com/path-1/path_2/file_1.js" },
866
0
    { "img-src http://test1.example.com/path-1/path_2/file-2.js",
867
0
      "img-src http://test1.example.com/path-1/path_2/file-2.js" },
868
0
    { "img-src http://test1.example.com/path-1/path_2/f.js",
869
0
      "img-src http://test1.example.com/path-1/path_2/f.js" },
870
0
    { "img-src http://test1.example.com/path-1/path_2/f.oo.js",
871
0
      "img-src http://test1.example.com/path-1/path_2/f.oo.js" },
872
0
    { "img-src test1.example.com",
873
0
      "img-src http://test1.example.com" },
874
0
    { "img-src test1.example.com/",
875
0
      "img-src http://test1.example.com/" },
876
0
    { "img-src test1.example.com/path-1",
877
0
      "img-src http://test1.example.com/path-1" },
878
0
    { "img-src test1.example.com/path-1/",
879
0
      "img-src http://test1.example.com/path-1/" },
880
0
    { "img-src test1.example.com/path-1/path_2/",
881
0
      "img-src http://test1.example.com/path-1/path_2/" },
882
0
    { "img-src test1.example.com/path-1/path_2/file.js",
883
0
      "img-src http://test1.example.com/path-1/path_2/file.js" },
884
0
    { "img-src test1.example.com/path-1/path_2/file_1.js",
885
0
      "img-src http://test1.example.com/path-1/path_2/file_1.js" },
886
0
    { "img-src test1.example.com/path-1/path_2/file-2.js",
887
0
      "img-src http://test1.example.com/path-1/path_2/file-2.js" },
888
0
    { "img-src test1.example.com/path-1/path_2/f.js",
889
0
      "img-src http://test1.example.com/path-1/path_2/f.js" },
890
0
    { "img-src test1.example.com/path-1/path_2/f.oo.js",
891
0
      "img-src http://test1.example.com/path-1/path_2/f.oo.js" },
892
0
    { "img-src *.example.com",
893
0
      "img-src http://*.example.com" },
894
0
    { "img-src *.example.com/",
895
0
      "img-src http://*.example.com/" },
896
0
    { "img-src *.example.com/path-1",
897
0
      "img-src http://*.example.com/path-1" },
898
0
    { "img-src *.example.com/path-1/",
899
0
      "img-src http://*.example.com/path-1/" },
900
0
    { "img-src *.example.com/path-1/path_2/",
901
0
      "img-src http://*.example.com/path-1/path_2/" },
902
0
    { "img-src *.example.com/path-1/path_2/file.js",
903
0
      "img-src http://*.example.com/path-1/path_2/file.js" },
904
0
    { "img-src *.example.com/path-1/path_2/file_1.js",
905
0
      "img-src http://*.example.com/path-1/path_2/file_1.js" },
906
0
    { "img-src *.example.com/path-1/path_2/file-2.js",
907
0
      "img-src http://*.example.com/path-1/path_2/file-2.js" },
908
0
    { "img-src *.example.com/path-1/path_2/f.js",
909
0
      "img-src http://*.example.com/path-1/path_2/f.js" },
910
0
    { "img-src *.example.com/path-1/path_2/f.oo.js",
911
0
      "img-src http://*.example.com/path-1/path_2/f.oo.js" },
912
0
    { "img-src test1.example.com:80",
913
0
      "img-src http://test1.example.com:80" },
914
0
    { "img-src test1.example.com:80/",
915
0
      "img-src http://test1.example.com:80/" },
916
0
    { "img-src test1.example.com:80/path-1",
917
0
      "img-src http://test1.example.com:80/path-1" },
918
0
    { "img-src test1.example.com:80/path-1/",
919
0
      "img-src http://test1.example.com:80/path-1/" },
920
0
    { "img-src test1.example.com:80/path-1/path_2",
921
0
      "img-src http://test1.example.com:80/path-1/path_2" },
922
0
    { "img-src test1.example.com:80/path-1/path_2/",
923
0
      "img-src http://test1.example.com:80/path-1/path_2/" },
924
0
    { "img-src test1.example.com:80/path-1/path_2/file.js",
925
0
      "img-src http://test1.example.com:80/path-1/path_2/file.js" },
926
0
    { "img-src test1.example.com:80/path-1/path_2/f.ile.js",
927
0
      "img-src http://test1.example.com:80/path-1/path_2/f.ile.js" },
928
0
    { "img-src test1.example.com:*",
929
0
      "img-src http://test1.example.com:*" },
930
0
    { "img-src test1.example.com:*/",
931
0
      "img-src http://test1.example.com:*/" },
932
0
    { "img-src test1.example.com:*/path-1",
933
0
      "img-src http://test1.example.com:*/path-1" },
934
0
    { "img-src test1.example.com:*/path-1/",
935
0
      "img-src http://test1.example.com:*/path-1/" },
936
0
    { "img-src test1.example.com:*/path-1/path_2",
937
0
      "img-src http://test1.example.com:*/path-1/path_2" },
938
0
    { "img-src test1.example.com:*/path-1/path_2/",
939
0
      "img-src http://test1.example.com:*/path-1/path_2/" },
940
0
    { "img-src test1.example.com:*/path-1/path_2/file.js",
941
0
      "img-src http://test1.example.com:*/path-1/path_2/file.js" },
942
0
    { "img-src test1.example.com:*/path-1/path_2/f.ile.js",
943
0
      "img-src http://test1.example.com:*/path-1/path_2/f.ile.js" },
944
0
    { "img-src http://test1.example.com/abc//",
945
0
      "img-src http://test1.example.com/abc//" },
946
0
    { "img-src https://test1.example.com/abc/def//",
947
0
      "img-src https://test1.example.com/abc/def//" },
948
0
    { "img-src https://test1.example.com/abc/def/ghi//",
949
0
      "img-src https://test1.example.com/abc/def/ghi//" },
950
0
    { "img-src http://test1.example.com:80/abc//",
951
0
      "img-src http://test1.example.com:80/abc//" },
952
0
    { "img-src https://test1.example.com:80/abc/def//",
953
0
      "img-src https://test1.example.com:80/abc/def//" },
954
0
    { "img-src https://test1.example.com:80/abc/def/ghi//",
955
0
      "img-src https://test1.example.com:80/abc/def/ghi//" },
956
0
    { "img-src https://test1.example.com/abc////////////def/",
957
0
      "img-src https://test1.example.com/abc////////////def/" },
958
0
    { "img-src https://test1.example.com/abc////////////",
959
0
      "img-src https://test1.example.com/abc////////////" },
960
0
  };
961
0
962
0
  uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
963
0
  ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)));
964
0
}
965
966
// ============ TestBadGeneratedPoliciesForPathHandling ============
967
968
TEST(CSPParser, BadGeneratedPoliciesForPathHandling)
969
0
{
970
0
  static const PolicyTest policies[] =
971
0
  {
972
0
    { "img-src test1.example.com:88path-1/",
973
0
      "img-src 'none'" },
974
0
    { "img-src test1.example.com:80.js",
975
0
      "img-src 'none'" },
976
0
    { "img-src test1.example.com:*.js",
977
0
      "img-src 'none'" },
978
0
    { "img-src test1.example.com:*.",
979
0
      "img-src 'none'" },
980
0
    { "img-src http://test1.example.com//",
981
0
      "img-src 'none'" },
982
0
    { "img-src http://test1.example.com:80//",
983
0
      "img-src 'none'" },
984
0
    { "img-src http://test1.example.com:80abc",
985
0
      "img-src 'none'" },
986
0
  };
987
0
988
0
  uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
989
0
  ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)));
990
0
}
991
992
// ============================= TestFuzzyPolicies ========================
993
994
// Use a policy, eliminate one character at a time,
995
// and feed it as input to the parser.
996
997
TEST(CSPParser, ShorteningPolicies)
998
0
{
999
0
  char pol[] = "default-src http://www.sub1.sub2.example.com:88/path1/path2/ 'unsafe-inline' 'none'";
1000
0
  uint32_t len = static_cast<uint32_t>(sizeof(pol));
1001
0
1002
0
  PolicyTest testPol[1];
1003
0
  memset(&testPol[0].policy, '\0', kMaxPolicyLength * sizeof(char));
1004
0
1005
0
  while (--len) {
1006
0
    memset(&testPol[0].policy, '\0', kMaxPolicyLength * sizeof(char));
1007
0
    memcpy(&testPol[0].policy, &pol, len * sizeof(char));
1008
0
    ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(testPol, 1,
1009
0
                                          kFuzzyExpectedPolicyCount)));
1010
0
  }
1011
0
}
1012
1013
// ============================= TestFuzzyPolicies ========================
1014
1015
// We generate kFuzzyRuns inputs by (pseudo) randomly picking from the 128
1016
// ASCII characters; feed them to the parser and verfy that the parser
1017
// handles the input gracefully.
1018
//
1019
// Please note, that by using srand(0) we get deterministic results!
1020
1021
#if RUN_OFFLINE_TESTS
1022
1023
TEST(CSPParser, FuzzyPolicies)
1024
{
1025
  // init srand with 0 so we get same results
1026
  srand(0);
1027
1028
  PolicyTest testPol[1];
1029
  memset(&testPol[0].policy, '\0', kMaxPolicyLength);
1030
1031
  for (uint32_t index = 0; index < kFuzzyRuns; index++) {
1032
    // randomly select the length of the next policy
1033
    uint32_t polLength = rand() % kMaxPolicyLength;
1034
    // reset memory of the policy string
1035
    memset(&testPol[0].policy, '\0', kMaxPolicyLength * sizeof(char));
1036
1037
    for (uint32_t i = 0; i < polLength; i++) {
1038
      // fill the policy array with random ASCII chars
1039
      testPol[0].policy[i] = static_cast<char>(rand() % 128);
1040
    }
1041
    ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(testPol, 1,
1042
                                          kFuzzyExpectedPolicyCount)));
1043
  }
1044
}
1045
1046
#endif
1047
1048
// ============================= TestFuzzyPoliciesIncDir ========================
1049
1050
// In a similar fashion as in TestFuzzyPolicies, we again (pseudo) randomly
1051
// generate input for the parser, but this time also include a valid directive
1052
// followed by the random input.
1053
1054
#if RUN_OFFLINE_TESTS
1055
1056
TEST(CSPParser, FuzzyPoliciesIncDir)
1057
{
1058
  // init srand with 0 so we get same results
1059
  srand(0);
1060
1061
  PolicyTest testPol[1];
1062
  memset(&testPol[0].policy, '\0', kMaxPolicyLength);
1063
1064
  char defaultSrc[] = "default-src ";
1065
  int defaultSrcLen = sizeof(defaultSrc) - 1;
1066
  // copy default-src into the policy array
1067
  memcpy(&testPol[0].policy, &defaultSrc, (defaultSrcLen * sizeof(char)));
1068
1069
  for (uint32_t index = 0; index < kFuzzyRuns; index++) {
1070
    // randomly select the length of the next policy
1071
    uint32_t polLength = rand() % (kMaxPolicyLength - defaultSrcLen);
1072
    // reset memory of the policy string, but leave default-src.
1073
    memset((&(testPol[0].policy) + (defaultSrcLen * sizeof(char))),
1074
           '\0', (kMaxPolicyLength - defaultSrcLen) * sizeof(char));
1075
1076
    // do not start at index 0 so we do not overwrite 'default-src'
1077
    for (uint32_t i = defaultSrcLen; i < polLength; i++) {
1078
      // fill the policy array with random ASCII chars
1079
      testPol[0].policy[i] = static_cast<char>(rand() % 128);
1080
    }
1081
    ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(testPol, 1,
1082
                                          kFuzzyExpectedPolicyCount)));
1083
  }
1084
}
1085
1086
#endif
1087
1088
// ============================= TestFuzzyPoliciesIncDirLimASCII ==============
1089
1090
// Same as TestFuzzyPoliciesIncDir() but using limited ASCII,
1091
// which represents more likely input.
1092
1093
#if RUN_OFFLINE_TESTS
1094
1095
TEST(CSPParser, FuzzyPoliciesIncDirLimASCII)
1096
{
1097
  char input[] = "1234567890" \
1098
                 "abcdefghijklmnopqrstuvwxyz" \
1099
                 "ABCDEFGHIJKLMNOPQRSTUVWZYZ" \
1100
                 "!@#^&*()-+_=";
1101
1102
  // init srand with 0 so we get same results
1103
  srand(0);
1104
1105
  PolicyTest testPol[1];
1106
  memset(&testPol[0].policy, '\0', kMaxPolicyLength);
1107
1108
  char defaultSrc[] = "default-src ";
1109
  int defaultSrcLen = sizeof(defaultSrc) - 1;
1110
  // copy default-src into the policy array
1111
  memcpy(&testPol[0].policy, &defaultSrc, (defaultSrcLen * sizeof(char)));
1112
1113
  for (uint32_t index = 0; index < kFuzzyRuns; index++) {
1114
    // randomly select the length of the next policy
1115
    uint32_t polLength = rand() % (kMaxPolicyLength - defaultSrcLen);
1116
    // reset memory of the policy string, but leave default-src.
1117
    memset((&(testPol[0].policy) + (defaultSrcLen * sizeof(char))),
1118
           '\0', (kMaxPolicyLength - defaultSrcLen) * sizeof(char));
1119
1120
    // do not start at index 0 so we do not overwrite 'default-src'
1121
    for (uint32_t i = defaultSrcLen; i < polLength; i++) {
1122
      // fill the policy array with chars from the pre-defined input
1123
      uint32_t inputIndex = rand() % sizeof(input);
1124
      testPol[0].policy[i] = input[inputIndex];
1125
    }
1126
    ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(testPol, 1,
1127
                                          kFuzzyExpectedPolicyCount)));
1128
  }
1129
}
1130
#endif