Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/frame/csp/CSPDirectiveList.h" | 5 #include "core/frame/csp/CSPDirectiveList.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/SourceLocation.h" | 7 #include "bindings/core/v8/SourceLocation.h" |
| 8 #include "core/dom/Document.h" | 8 #include "core/dom/Document.h" |
| 9 #include "core/dom/SecurityContext.h" | 9 #include "core/dom/SecurityContext.h" |
| 10 #include "core/dom/SpaceSplitString.h" | 10 #include "core/dom/SpaceSplitString.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 117 ContentSecurityPolicy::URLViolation, frame); | 117 ContentSecurityPolicy::URLViolation, frame); |
| 118 } | 118 } |
| 119 | 119 |
| 120 void CSPDirectiveList::reportViolationWithLocation( | 120 void CSPDirectiveList::reportViolationWithLocation( |
| 121 const String& directiveText, | 121 const String& directiveText, |
| 122 const ContentSecurityPolicy::DirectiveType& effectiveType, | 122 const ContentSecurityPolicy::DirectiveType& effectiveType, |
| 123 const String& consoleMessage, | 123 const String& consoleMessage, |
| 124 const KURL& blockedURL, | 124 const KURL& blockedURL, |
| 125 const String& contextURL, | 125 const String& contextURL, |
| 126 const WTF::OrdinalNumber& contextLine, | 126 const WTF::OrdinalNumber& contextLine, |
| 127 Element* element) const { | 127 Element* element, |
| 128 const String& source) const { | |
| 128 String message = | 129 String message = |
| 129 isReportOnly() ? "[Report Only] " + consoleMessage : consoleMessage; | 130 isReportOnly() ? "[Report Only] " + consoleMessage : consoleMessage; |
| 130 m_policy->logToConsole(ConsoleMessage::create( | 131 m_policy->logToConsole(ConsoleMessage::create( |
| 131 SecurityMessageSource, ErrorMessageLevel, message, | 132 SecurityMessageSource, ErrorMessageLevel, message, |
| 132 SourceLocation::capture(contextURL, contextLine.oneBasedInt(), 0))); | 133 SourceLocation::capture(contextURL, contextLine.oneBasedInt(), 0))); |
| 133 m_policy->reportViolation( | 134 m_policy->reportViolation( |
| 134 directiveText, effectiveType, message, blockedURL, m_reportEndpoints, | 135 directiveText, effectiveType, message, blockedURL, m_reportEndpoints, |
| 135 m_header, m_headerType, ContentSecurityPolicy::InlineViolation, nullptr, | 136 m_header, m_headerType, ContentSecurityPolicy::InlineViolation, nullptr, |
| 136 RedirectStatus::NoRedirect, contextLine.oneBasedInt(), element); | 137 RedirectStatus::NoRedirect, contextLine.oneBasedInt(), element, source); |
| 137 } | 138 } |
| 138 | 139 |
| 139 void CSPDirectiveList::reportViolationWithState( | 140 void CSPDirectiveList::reportViolationWithState( |
| 140 const String& directiveText, | 141 const String& directiveText, |
| 141 const ContentSecurityPolicy::DirectiveType& effectiveType, | 142 const ContentSecurityPolicy::DirectiveType& effectiveType, |
| 142 const String& message, | 143 const String& message, |
| 143 const KURL& blockedURL, | 144 const KURL& blockedURL, |
| 144 ScriptState* scriptState, | 145 ScriptState* scriptState, |
| 145 const ContentSecurityPolicy::ExceptionStatus exceptionStatus) const { | 146 const ContentSecurityPolicy::ExceptionStatus exceptionStatus) const { |
| 146 String reportMessage = isReportOnly() ? "[Report Only] " + message : message; | 147 String reportMessage = isReportOnly() ? "[Report Only] " + message : message; |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 reportViolation( | 370 reportViolation( |
| 370 directive->text(), ContentSecurityPolicy::DirectiveType::PluginTypes, | 371 directive->text(), ContentSecurityPolicy::DirectiveType::PluginTypes, |
| 371 message + "\n", KURL(), ResourceRequest::RedirectStatus::NoRedirect); | 372 message + "\n", KURL(), ResourceRequest::RedirectStatus::NoRedirect); |
| 372 return denyIfEnforcingPolicy(); | 373 return denyIfEnforcingPolicy(); |
| 373 } | 374 } |
| 374 | 375 |
| 375 bool CSPDirectiveList::checkInlineAndReportViolation( | 376 bool CSPDirectiveList::checkInlineAndReportViolation( |
| 376 SourceListDirective* directive, | 377 SourceListDirective* directive, |
| 377 const String& consoleMessage, | 378 const String& consoleMessage, |
| 378 Element* element, | 379 Element* element, |
| 380 const String& source, | |
| 379 const String& contextURL, | 381 const String& contextURL, |
| 380 const WTF::OrdinalNumber& contextLine, | 382 const WTF::OrdinalNumber& contextLine, |
| 381 bool isScript, | 383 bool isScript, |
| 382 const String& hashValue) const { | 384 const String& hashValue) const { |
| 383 if (!directive || directive->allowAllInline()) | 385 if (!directive || directive->allowAllInline()) |
| 384 return true; | 386 return true; |
| 385 | 387 |
| 386 String suffix = String(); | 388 String suffix = String(); |
| 387 if (directive->allowInline() && directive->isHashOrNoncePresent()) { | 389 if (directive->allowInline() && directive->isHashOrNoncePresent()) { |
| 388 // If inline is allowed, but a hash or nonce is present, we ignore | 390 // If inline is allowed, but a hash or nonce is present, we ignore |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 399 String(isScript ? "script" : "style") + | 401 String(isScript ? "script" : "style") + |
| 400 "-src' was not explicitly set, so 'default-src' is used as a " | 402 "-src' was not explicitly set, so 'default-src' is used as a " |
| 401 "fallback."; | 403 "fallback."; |
| 402 } | 404 } |
| 403 | 405 |
| 404 reportViolationWithLocation( | 406 reportViolationWithLocation( |
| 405 directive->text(), | 407 directive->text(), |
| 406 isScript ? ContentSecurityPolicy::DirectiveType::ScriptSrc | 408 isScript ? ContentSecurityPolicy::DirectiveType::ScriptSrc |
| 407 : ContentSecurityPolicy::DirectiveType::StyleSrc, | 409 : ContentSecurityPolicy::DirectiveType::StyleSrc, |
| 408 consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), | 410 consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), |
| 409 contextURL, contextLine, element); | 411 contextURL, contextLine, element, |
| 412 directive->allowReportSample() ? source : emptyString); | |
|
andypaicu
2017/02/22 12:47:03
Minor nit: perhaps we can start passing from here
Mike West
2017/02/22 14:54:00
I'd prefer to keep the sanitization bits in `::rep
| |
| 410 | 413 |
| 411 if (!isReportOnly()) { | 414 if (!isReportOnly()) { |
| 412 if (isScript) | 415 if (isScript) |
| 413 m_policy->reportBlockedScriptExecutionToInspector(directive->text()); | 416 m_policy->reportBlockedScriptExecutionToInspector(directive->text()); |
| 414 return false; | 417 return false; |
| 415 } | 418 } |
| 416 return true; | 419 return true; |
| 417 } | 420 } |
| 418 | 421 |
| 419 bool CSPDirectiveList::checkSourceAndReportViolation( | 422 bool CSPDirectiveList::checkSourceAndReportViolation( |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 496 "' in a frame because an ancestor violates the " | 499 "' in a frame because an ancestor violates the " |
| 497 "following Content Security Policy directive: " | 500 "following Content Security Policy directive: " |
| 498 "\"" + | 501 "\"" + |
| 499 directive->text() + "\".", | 502 directive->text() + "\".", |
| 500 url, frame); | 503 url, frame); |
| 501 return denyIfEnforcingPolicy(); | 504 return denyIfEnforcingPolicy(); |
| 502 } | 505 } |
| 503 | 506 |
| 504 bool CSPDirectiveList::allowJavaScriptURLs( | 507 bool CSPDirectiveList::allowJavaScriptURLs( |
| 505 Element* element, | 508 Element* element, |
| 509 const String& source, | |
| 506 const String& contextURL, | 510 const String& contextURL, |
| 507 const WTF::OrdinalNumber& contextLine, | 511 const WTF::OrdinalNumber& contextLine, |
| 508 ContentSecurityPolicy::ReportingStatus reportingStatus) const { | 512 ContentSecurityPolicy::ReportingStatus reportingStatus) const { |
| 509 SourceListDirective* directive = operativeDirective(m_scriptSrc.get()); | 513 SourceListDirective* directive = operativeDirective(m_scriptSrc.get()); |
| 510 if (reportingStatus == ContentSecurityPolicy::SendReport) { | 514 if (reportingStatus == ContentSecurityPolicy::SendReport) { |
| 511 return checkInlineAndReportViolation( | 515 return checkInlineAndReportViolation( |
| 512 directive, | 516 directive, |
| 513 "Refused to execute JavaScript URL because it violates the following " | 517 "Refused to execute JavaScript URL because it violates the following " |
| 514 "Content Security Policy directive: ", | 518 "Content Security Policy directive: ", |
| 515 element, contextURL, contextLine, true, "sha256-..."); | 519 element, source, contextURL, contextLine, true, "sha256-..."); |
| 516 } | 520 } |
| 517 | 521 |
| 518 return !directive || directive->allowAllInline(); | 522 return !directive || directive->allowAllInline(); |
| 519 } | 523 } |
| 520 | 524 |
| 521 bool CSPDirectiveList::allowInlineEventHandlers( | 525 bool CSPDirectiveList::allowInlineEventHandlers( |
| 522 Element* element, | 526 Element* element, |
| 527 const String& source, | |
| 523 const String& contextURL, | 528 const String& contextURL, |
| 524 const WTF::OrdinalNumber& contextLine, | 529 const WTF::OrdinalNumber& contextLine, |
| 525 ContentSecurityPolicy::ReportingStatus reportingStatus) const { | 530 ContentSecurityPolicy::ReportingStatus reportingStatus) const { |
| 526 SourceListDirective* directive = operativeDirective(m_scriptSrc.get()); | 531 SourceListDirective* directive = operativeDirective(m_scriptSrc.get()); |
| 527 if (reportingStatus == ContentSecurityPolicy::SendReport) { | 532 if (reportingStatus == ContentSecurityPolicy::SendReport) { |
| 528 return checkInlineAndReportViolation( | 533 return checkInlineAndReportViolation( |
| 529 operativeDirective(m_scriptSrc.get()), | 534 operativeDirective(m_scriptSrc.get()), |
| 530 "Refused to execute inline event handler because it violates the " | 535 "Refused to execute inline event handler because it violates the " |
| 531 "following Content Security Policy directive: ", | 536 "following Content Security Policy directive: ", |
| 532 element, contextURL, contextLine, true, "sha256-..."); | 537 element, source, contextURL, contextLine, true, "sha256-..."); |
| 533 } | 538 } |
| 534 | 539 |
| 535 return !directive || directive->allowAllInline(); | 540 return !directive || directive->allowAllInline(); |
| 536 } | 541 } |
| 537 | 542 |
| 538 bool CSPDirectiveList::allowInlineScript( | 543 bool CSPDirectiveList::allowInlineScript( |
| 539 Element* element, | 544 Element* element, |
| 540 const String& contextURL, | 545 const String& contextURL, |
| 541 const String& nonce, | 546 const String& nonce, |
| 542 const WTF::OrdinalNumber& contextLine, | 547 const WTF::OrdinalNumber& contextLine, |
| 543 ContentSecurityPolicy::ReportingStatus reportingStatus, | 548 ContentSecurityPolicy::ReportingStatus reportingStatus, |
| 544 const String& content) const { | 549 const String& content) const { |
| 545 SourceListDirective* directive = operativeDirective(m_scriptSrc.get()); | 550 SourceListDirective* directive = operativeDirective(m_scriptSrc.get()); |
| 546 if (isMatchingNoncePresent(directive, nonce)) | 551 if (isMatchingNoncePresent(directive, nonce)) |
| 547 return true; | 552 return true; |
| 548 if (element && isHTMLScriptElement(element) && | 553 if (element && isHTMLScriptElement(element) && |
| 549 !toHTMLScriptElement(element)->loader()->isParserInserted() && | 554 !toHTMLScriptElement(element)->loader()->isParserInserted() && |
| 550 allowDynamic()) { | 555 allowDynamic()) { |
| 551 return true; | 556 return true; |
| 552 } | 557 } |
| 553 if (reportingStatus == ContentSecurityPolicy::SendReport) { | 558 if (reportingStatus == ContentSecurityPolicy::SendReport) { |
| 554 return checkInlineAndReportViolation( | 559 return checkInlineAndReportViolation( |
| 555 directive, | 560 directive, |
| 556 "Refused to execute inline script because it violates the following " | 561 "Refused to execute inline script because it violates the following " |
| 557 "Content Security Policy directive: ", | 562 "Content Security Policy directive: ", |
| 558 element, contextURL, contextLine, true, getSha256String(content)); | 563 element, content, contextURL, contextLine, true, |
| 564 getSha256String(content)); | |
| 559 } | 565 } |
| 560 | 566 |
| 561 return !directive || directive->allowAllInline(); | 567 return !directive || directive->allowAllInline(); |
| 562 } | 568 } |
| 563 | 569 |
| 564 bool CSPDirectiveList::allowInlineStyle( | 570 bool CSPDirectiveList::allowInlineStyle( |
| 565 Element* element, | 571 Element* element, |
| 566 const String& contextURL, | 572 const String& contextURL, |
| 567 const String& nonce, | 573 const String& nonce, |
| 568 const WTF::OrdinalNumber& contextLine, | 574 const WTF::OrdinalNumber& contextLine, |
| 569 ContentSecurityPolicy::ReportingStatus reportingStatus, | 575 ContentSecurityPolicy::ReportingStatus reportingStatus, |
| 570 const String& content) const { | 576 const String& content) const { |
| 571 SourceListDirective* directive = operativeDirective(m_styleSrc.get()); | 577 SourceListDirective* directive = operativeDirective(m_styleSrc.get()); |
| 572 if (isMatchingNoncePresent(directive, nonce)) | 578 if (isMatchingNoncePresent(directive, nonce)) |
| 573 return true; | 579 return true; |
| 574 if (reportingStatus == ContentSecurityPolicy::SendReport) { | 580 if (reportingStatus == ContentSecurityPolicy::SendReport) { |
| 575 return checkInlineAndReportViolation( | 581 return checkInlineAndReportViolation( |
| 576 directive, | 582 directive, |
| 577 "Refused to apply inline style because it violates the following " | 583 "Refused to apply inline style because it violates the following " |
| 578 "Content Security Policy directive: ", | 584 "Content Security Policy directive: ", |
| 579 element, contextURL, contextLine, false, getSha256String(content)); | 585 element, String(), contextURL, contextLine, false, |
| 586 getSha256String(content)); | |
| 580 } | 587 } |
| 581 | 588 |
| 582 return !directive || directive->allowAllInline(); | 589 return !directive || directive->allowAllInline(); |
| 583 } | 590 } |
| 584 | 591 |
| 585 bool CSPDirectiveList::allowEval( | 592 bool CSPDirectiveList::allowEval( |
| 586 ScriptState* scriptState, | 593 ScriptState* scriptState, |
| 587 ContentSecurityPolicy::ReportingStatus reportingStatus, | 594 ContentSecurityPolicy::ReportingStatus reportingStatus, |
| 588 ContentSecurityPolicy::ExceptionStatus exceptionStatus) const { | 595 ContentSecurityPolicy::ExceptionStatus exceptionStatus) const { |
| 589 if (reportingStatus == ContentSecurityPolicy::SendReport) { | 596 if (reportingStatus == ContentSecurityPolicy::SendReport) { |
| (...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1323 visitor->trace(m_imgSrc); | 1330 visitor->trace(m_imgSrc); |
| 1324 visitor->trace(m_mediaSrc); | 1331 visitor->trace(m_mediaSrc); |
| 1325 visitor->trace(m_manifestSrc); | 1332 visitor->trace(m_manifestSrc); |
| 1326 visitor->trace(m_objectSrc); | 1333 visitor->trace(m_objectSrc); |
| 1327 visitor->trace(m_scriptSrc); | 1334 visitor->trace(m_scriptSrc); |
| 1328 visitor->trace(m_styleSrc); | 1335 visitor->trace(m_styleSrc); |
| 1329 visitor->trace(m_workerSrc); | 1336 visitor->trace(m_workerSrc); |
| 1330 } | 1337 } |
| 1331 | 1338 |
| 1332 } // namespace blink | 1339 } // namespace blink |
| OLD | NEW |