| 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 |