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 |