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