Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(137)

Side by Side Diff: third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp

Issue 1923273002: CSP: Allow hashed inline event handlers only with 'unsafe-hashed-attributes' (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698