OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Google, Inc. All rights reserved. | 2 * Copyright (C) 2011 Google, Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 template<bool (CSPDirectiveList::*allowed)(const String&) const> | 365 template<bool (CSPDirectiveList::*allowed)(const String&) const> |
366 bool isAllowedByAllWithNonce(const CSPDirectiveListVector& policies, const Strin
g& nonce) | 366 bool isAllowedByAllWithNonce(const CSPDirectiveListVector& policies, const Strin
g& nonce) |
367 { | 367 { |
368 for (const auto& policy : policies) { | 368 for (const auto& policy : policies) { |
369 if (!(policy.get()->*allowed)(nonce)) | 369 if (!(policy.get()->*allowed)(nonce)) |
370 return false; | 370 return false; |
371 } | 371 } |
372 return true; | 372 return true; |
373 } | 373 } |
374 | 374 |
375 template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&) const> | 375 template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&, ContentSecurityP
olicy::InlineType) const> |
376 bool isAllowedByAllWithHash(const CSPDirectiveListVector& policies, const CSPHas
hValue& hashValue) | 376 bool isAllowedByAllWithHash(const CSPDirectiveListVector& policies, const CSPHas
hValue& hashValue, ContentSecurityPolicy::InlineType type) |
377 { | 377 { |
378 for (const auto& policy : policies) { | 378 for (const auto& policy : policies) { |
379 if (!(policy.get()->*allowed)(hashValue)) | 379 if (!(policy.get()->*allowed)(hashValue, type)) |
380 return false; | 380 return false; |
381 } | 381 } |
382 return true; | 382 return true; |
383 } | 383 } |
384 | 384 |
385 template <bool (CSPDirectiveList::*allowFromURL)(const KURL&, ContentSecurityPol
icy::RedirectStatus, ContentSecurityPolicy::ReportingStatus) const> | 385 template <bool (CSPDirectiveList::*allowFromURL)(const KURL&, ContentSecurityPol
icy::RedirectStatus, ContentSecurityPolicy::ReportingStatus) const> |
386 bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const KURL& u
rl, ContentSecurityPolicy::RedirectStatus redirectStatus, ContentSecurityPolicy:
:ReportingStatus reportingStatus) | 386 bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const KURL& u
rl, ContentSecurityPolicy::RedirectStatus redirectStatus, ContentSecurityPolicy:
:ReportingStatus reportingStatus) |
387 { | 387 { |
388 if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol())) | 388 if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol())) |
389 return true; | 389 return true; |
390 | 390 |
391 for (const auto& policy : policies) { | 391 for (const auto& policy : policies) { |
392 if (!(policy.get()->*allowFromURL)(url, redirectStatus, reportingStatus)
) | 392 if (!(policy.get()->*allowFromURL)(url, redirectStatus, reportingStatus)
) |
393 return false; | 393 return false; |
394 } | 394 } |
395 return true; | 395 return true; |
396 } | 396 } |
397 | 397 |
398 template<bool (CSPDirectiveList::*allowed)(LocalFrame*, const KURL&, ContentSecu
rityPolicy::ReportingStatus) const> | 398 template<bool (CSPDirectiveList::*allowed)(LocalFrame*, const KURL&, ContentSecu
rityPolicy::ReportingStatus) const> |
399 bool isAllowedByAllWithFrame(const CSPDirectiveListVector& policies, LocalFrame*
frame, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) | 399 bool isAllowedByAllWithFrame(const CSPDirectiveListVector& policies, LocalFrame*
frame, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) |
400 { | 400 { |
401 for (const auto& policy : policies) { | 401 for (const auto& policy : policies) { |
402 if (!(policy.get()->*allowed)(frame, url, reportingStatus)) | 402 if (!(policy.get()->*allowed)(frame, url, reportingStatus)) |
403 return false; | 403 return false; |
404 } | 404 } |
405 return true; | 405 return true; |
406 } | 406 } |
407 | 407 |
408 template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&) const> | 408 template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&, ContentSecurityP
olicy::InlineType) const> |
409 bool checkDigest(const String& source, uint8_t hashAlgorithmsUsed, const CSPDire
ctiveListVector& policies) | 409 bool checkDigest(const String& source, ContentSecurityPolicy::InlineType type, u
int8_t hashAlgorithmsUsed, const CSPDirectiveListVector& policies) |
410 { | 410 { |
411 // Any additions or subtractions from this struct should also modify the | 411 // Any additions or subtractions from this struct should also modify the |
412 // respective entries in the kSupportedPrefixes array in | 412 // respective entries in the kSupportedPrefixes array in |
413 // CSPSourceList::parseHash(). | 413 // CSPSourceList::parseHash(). |
414 static const struct { | 414 static const struct { |
415 ContentSecurityPolicyHashAlgorithm cspHashAlgorithm; | 415 ContentSecurityPolicyHashAlgorithm cspHashAlgorithm; |
416 HashAlgorithm algorithm; | 416 HashAlgorithm algorithm; |
417 } kAlgorithmMap[] = { | 417 } kAlgorithmMap[] = { |
418 { ContentSecurityPolicyHashAlgorithmSha1, HashAlgorithmSha1 }, | 418 { ContentSecurityPolicyHashAlgorithmSha1, HashAlgorithmSha1 }, |
419 { ContentSecurityPolicyHashAlgorithmSha256, HashAlgorithmSha256 }, | 419 { ContentSecurityPolicyHashAlgorithmSha256, HashAlgorithmSha256 }, |
420 { ContentSecurityPolicyHashAlgorithmSha384, HashAlgorithmSha384 }, | 420 { ContentSecurityPolicyHashAlgorithmSha384, HashAlgorithmSha384 }, |
421 { ContentSecurityPolicyHashAlgorithmSha512, HashAlgorithmSha512 } | 421 { ContentSecurityPolicyHashAlgorithmSha512, HashAlgorithmSha512 } |
422 }; | 422 }; |
423 | 423 |
424 // Only bother normalizing the source/computing digests if there are any che
cks to be done. | 424 // Only bother normalizing the source/computing digests if there are any che
cks to be done. |
425 if (hashAlgorithmsUsed == ContentSecurityPolicyHashAlgorithmNone) | 425 if (hashAlgorithmsUsed == ContentSecurityPolicyHashAlgorithmNone) |
426 return false; | 426 return false; |
427 | 427 |
428 StringUTF8Adaptor utf8Source(source); | 428 StringUTF8Adaptor utf8Source(source); |
429 | 429 |
430 for (const auto& algorithmMap : kAlgorithmMap) { | 430 for (const auto& algorithmMap : kAlgorithmMap) { |
431 DigestValue digest; | 431 DigestValue digest; |
432 if (algorithmMap.cspHashAlgorithm & hashAlgorithmsUsed) { | 432 if (algorithmMap.cspHashAlgorithm & hashAlgorithmsUsed) { |
433 bool digestSuccess = computeDigest(algorithmMap.algorithm, utf8Sourc
e.data(), utf8Source.length(), digest); | 433 bool digestSuccess = computeDigest(algorithmMap.algorithm, utf8Sourc
e.data(), utf8Source.length(), digest); |
434 if (digestSuccess && isAllowedByAllWithHash<allowed>(policies, CSPHa
shValue(algorithmMap.cspHashAlgorithm, digest))) | 434 if (digestSuccess && isAllowedByAllWithHash<allowed>(policies, CSPHa
shValue(algorithmMap.cspHashAlgorithm, digest), type)) |
435 return true; | 435 return true; |
436 } | 436 } |
437 } | 437 } |
438 | 438 |
439 return false; | 439 return false; |
440 } | 440 } |
441 | 441 |
442 bool ContentSecurityPolicy::allowJavaScriptURLs(const String& contextURL, const
WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportin
gStatus) const | 442 bool ContentSecurityPolicy::allowJavaScriptURLs(const String& contextURL, const
WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportin
gStatus) const |
443 { | 443 { |
444 return isAllowedByAllWithContext<&CSPDirectiveList::allowJavaScriptURLs>(m_p
olicies, contextURL, contextLine, reportingStatus); | 444 return isAllowedByAllWithContext<&CSPDirectiveList::allowJavaScriptURLs>(m_p
olicies, contextURL, contextLine, reportingStatus); |
445 } | 445 } |
446 | 446 |
447 bool ContentSecurityPolicy::allowInlineEventHandlers(const String& contextURL, c
onst WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus rep
ortingStatus) const | 447 bool ContentSecurityPolicy::allowInlineEventHandler(const String& source, const
String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy
::ReportingStatus reportingStatus) const |
448 { | 448 { |
| 449 // Inline event handlers may be whitelisted by hash, if 'unsafe-hash-attribu
tes' is present in a policy. Check |
| 450 // against the digest of the |source| first before proceeding on to checking
whether inline script is allowed. |
| 451 if (checkDigest<&CSPDirectiveList::allowScriptHash>(source, InlineType::Attr
ibute, m_scriptHashAlgorithmsUsed, m_policies)) |
| 452 return true; |
449 return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineEventHandlers
>(m_policies, contextURL, contextLine, reportingStatus); | 453 return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineEventHandlers
>(m_policies, contextURL, contextLine, reportingStatus); |
450 } | 454 } |
451 | 455 |
452 bool ContentSecurityPolicy::allowInlineScript(const String& contextURL, const WT
F::OrdinalNumber& contextLine, const String& scriptContent, ContentSecurityPolic
y::ReportingStatus reportingStatus) const | 456 bool ContentSecurityPolicy::allowInlineScript(const String& contextURL, const WT
F::OrdinalNumber& contextLine, const String& scriptContent, ContentSecurityPolic
y::ReportingStatus reportingStatus) const |
453 { | 457 { |
454 return isAllowedByAllWithContextAndContent<&CSPDirectiveList::allowInlineScr
ipt>(m_policies, contextURL, contextLine, reportingStatus, scriptContent); | 458 return isAllowedByAllWithContextAndContent<&CSPDirectiveList::allowInlineScr
ipt>(m_policies, contextURL, contextLine, reportingStatus, scriptContent); |
455 } | 459 } |
456 | 460 |
457 bool ContentSecurityPolicy::allowInlineStyle(const String& contextURL, const WTF
::OrdinalNumber& contextLine, const String& styleContent, ContentSecurityPolicy:
:ReportingStatus reportingStatus) const | 461 bool ContentSecurityPolicy::allowInlineStyle(const String& contextURL, const WTF
::OrdinalNumber& contextLine, const String& styleContent, ContentSecurityPolicy:
:ReportingStatus reportingStatus) const |
458 { | 462 { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 bool ContentSecurityPolicy::allowScriptWithNonce(const String& nonce) const | 525 bool ContentSecurityPolicy::allowScriptWithNonce(const String& nonce) const |
522 { | 526 { |
523 return isAllowedByAllWithNonce<&CSPDirectiveList::allowScriptNonce>(m_polici
es, nonce); | 527 return isAllowedByAllWithNonce<&CSPDirectiveList::allowScriptNonce>(m_polici
es, nonce); |
524 } | 528 } |
525 | 529 |
526 bool ContentSecurityPolicy::allowStyleWithNonce(const String& nonce) const | 530 bool ContentSecurityPolicy::allowStyleWithNonce(const String& nonce) const |
527 { | 531 { |
528 return isAllowedByAllWithNonce<&CSPDirectiveList::allowStyleNonce>(m_policie
s, nonce); | 532 return isAllowedByAllWithNonce<&CSPDirectiveList::allowStyleNonce>(m_policie
s, nonce); |
529 } | 533 } |
530 | 534 |
531 bool ContentSecurityPolicy::allowScriptWithHash(const String& source) const | 535 bool ContentSecurityPolicy::allowScriptWithHash(const String& source, InlineType
type) const |
532 { | 536 { |
533 return checkDigest<&CSPDirectiveList::allowScriptHash>(source, m_scriptHashA
lgorithmsUsed, m_policies); | 537 return checkDigest<&CSPDirectiveList::allowScriptHash>(source, type, m_scrip
tHashAlgorithmsUsed, m_policies); |
534 } | 538 } |
535 | 539 |
536 bool ContentSecurityPolicy::allowStyleWithHash(const String& source) const | 540 bool ContentSecurityPolicy::allowStyleWithHash(const String& source, InlineType
type) const |
537 { | 541 { |
538 return checkDigest<&CSPDirectiveList::allowStyleHash>(source, m_styleHashAlg
orithmsUsed, m_policies); | 542 return checkDigest<&CSPDirectiveList::allowStyleHash>(source, type, m_styleH
ashAlgorithmsUsed, m_policies); |
539 } | 543 } |
540 | 544 |
541 bool ContentSecurityPolicy::allowRequest(WebURLRequest::RequestContext context,
const KURL& url, RedirectStatus redirectStatus, ReportingStatus reportingStatus)
const | 545 bool ContentSecurityPolicy::allowRequest(WebURLRequest::RequestContext context,
const KURL& url, RedirectStatus redirectStatus, ReportingStatus reportingStatus)
const |
542 { | 546 { |
543 switch (context) { | 547 switch (context) { |
544 case WebURLRequest::RequestContextAudio: | 548 case WebURLRequest::RequestContextAudio: |
545 case WebURLRequest::RequestContextTrack: | 549 case WebURLRequest::RequestContextTrack: |
546 case WebURLRequest::RequestContextVideo: | 550 case WebURLRequest::RequestContextVideo: |
547 return allowMediaFromSource(url, redirectStatus, reportingStatus); | 551 return allowMediaFromSource(url, redirectStatus, reportingStatus); |
548 case WebURLRequest::RequestContextBeacon: | 552 case WebURLRequest::RequestContextBeacon: |
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1063 // Collisions have no security impact, so we can save space by storing only
the string's hash rather than the whole report. | 1067 // Collisions have no security impact, so we can save space by storing only
the string's hash rather than the whole report. |
1064 return !m_violationReportsSent.contains(report.impl()->hash()); | 1068 return !m_violationReportsSent.contains(report.impl()->hash()); |
1065 } | 1069 } |
1066 | 1070 |
1067 void ContentSecurityPolicy::didSendViolationReport(const String& report) | 1071 void ContentSecurityPolicy::didSendViolationReport(const String& report) |
1068 { | 1072 { |
1069 m_violationReportsSent.add(report.impl()->hash()); | 1073 m_violationReportsSent.add(report.impl()->hash()); |
1070 } | 1074 } |
1071 | 1075 |
1072 } // namespace blink | 1076 } // namespace blink |
OLD | NEW |