Chromium Code Reviews| 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 13 matching lines...) Expand all Loading... | |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "core/frame/csp/ContentSecurityPolicy.h" | 26 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 27 | 27 |
| 28 #include "bindings/core/v8/ScriptController.h" | 28 #include "bindings/core/v8/ScriptController.h" |
| 29 #include "bindings/core/v8/SourceLocation.h" | 29 #include "bindings/core/v8/SourceLocation.h" |
| 30 #include "core/dom/DOMStringList.h" | 30 #include "core/dom/DOMStringList.h" |
| 31 #include "core/dom/Document.h" | 31 #include "core/dom/Document.h" |
| 32 #include "core/dom/SandboxFlags.h" | 32 #include "core/dom/SandboxFlags.h" |
| 33 #include "core/events/SecurityPolicyViolationEvent.h" | 33 #include "core/events/SecurityPolicyViolationEvent.h" |
| 34 #include "core/fetch/IntegrityMetadata.h" | |
| 34 #include "core/frame/FrameClient.h" | 35 #include "core/frame/FrameClient.h" |
| 35 #include "core/frame/LocalDOMWindow.h" | 36 #include "core/frame/LocalDOMWindow.h" |
| 36 #include "core/frame/LocalFrame.h" | 37 #include "core/frame/LocalFrame.h" |
| 37 #include "core/frame/UseCounter.h" | 38 #include "core/frame/UseCounter.h" |
| 38 #include "core/frame/csp/CSPDirectiveList.h" | 39 #include "core/frame/csp/CSPDirectiveList.h" |
| 39 #include "core/frame/csp/CSPSource.h" | 40 #include "core/frame/csp/CSPSource.h" |
| 40 #include "core/frame/csp/CSPSourceList.h" | 41 #include "core/frame/csp/CSPSourceList.h" |
| 41 #include "core/frame/csp/MediaListDirective.h" | 42 #include "core/frame/csp/MediaListDirective.h" |
| 42 #include "core/frame/csp/SourceListDirective.h" | 43 #include "core/frame/csp/SourceListDirective.h" |
| 43 #include "core/inspector/ConsoleMessage.h" | 44 #include "core/inspector/ConsoleMessage.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 95 // Mixed Content Directive | 96 // Mixed Content Directive |
| 96 // https://w3c.github.io/webappsec/specs/mixedcontent/#strict-mode | 97 // https://w3c.github.io/webappsec/specs/mixedcontent/#strict-mode |
| 97 const char ContentSecurityPolicy::BlockAllMixedContent[] = "block-all-mixed-cont ent"; | 98 const char ContentSecurityPolicy::BlockAllMixedContent[] = "block-all-mixed-cont ent"; |
| 98 | 99 |
| 99 // https://w3c.github.io/webappsec/specs/upgrade/ | 100 // https://w3c.github.io/webappsec/specs/upgrade/ |
| 100 const char ContentSecurityPolicy::UpgradeInsecureRequests[] = "upgrade-insecure- requests"; | 101 const char ContentSecurityPolicy::UpgradeInsecureRequests[] = "upgrade-insecure- requests"; |
| 101 | 102 |
| 102 // https://mikewest.github.io/cors-rfc1918/#csp | 103 // https://mikewest.github.io/cors-rfc1918/#csp |
| 103 const char ContentSecurityPolicy::TreatAsPublicAddress[] = "treat-as-public-addr ess"; | 104 const char ContentSecurityPolicy::TreatAsPublicAddress[] = "treat-as-public-addr ess"; |
| 104 | 105 |
| 106 // https://w3c.github.io/webappsec-subresource-integrity/#require-sri-for | |
| 107 const char ContentSecurityPolicy::RequireSRIFor[] = "require-sri-for"; | |
| 108 | |
| 105 bool ContentSecurityPolicy::isDirectiveName(const String& name) | 109 bool ContentSecurityPolicy::isDirectiveName(const String& name) |
| 106 { | 110 { |
| 107 return (equalIgnoringCase(name, ConnectSrc) | 111 return (equalIgnoringCase(name, ConnectSrc) |
| 108 || equalIgnoringCase(name, DefaultSrc) | 112 || equalIgnoringCase(name, DefaultSrc) |
| 109 || equalIgnoringCase(name, FontSrc) | 113 || equalIgnoringCase(name, FontSrc) |
| 110 || equalIgnoringCase(name, FrameSrc) | 114 || equalIgnoringCase(name, FrameSrc) |
| 111 || equalIgnoringCase(name, ImgSrc) | 115 || equalIgnoringCase(name, ImgSrc) |
| 112 || equalIgnoringCase(name, MediaSrc) | 116 || equalIgnoringCase(name, MediaSrc) |
| 113 || equalIgnoringCase(name, ObjectSrc) | 117 || equalIgnoringCase(name, ObjectSrc) |
| 114 || equalIgnoringCase(name, ReportURI) | 118 || equalIgnoringCase(name, ReportURI) |
| 115 || equalIgnoringCase(name, Sandbox) | 119 || equalIgnoringCase(name, Sandbox) |
| 116 || equalIgnoringCase(name, ScriptSrc) | 120 || equalIgnoringCase(name, ScriptSrc) |
| 117 || equalIgnoringCase(name, StyleSrc) | 121 || equalIgnoringCase(name, StyleSrc) |
| 118 || equalIgnoringCase(name, BaseURI) | 122 || equalIgnoringCase(name, BaseURI) |
| 119 || equalIgnoringCase(name, ChildSrc) | 123 || equalIgnoringCase(name, ChildSrc) |
| 120 || equalIgnoringCase(name, FormAction) | 124 || equalIgnoringCase(name, FormAction) |
| 121 || equalIgnoringCase(name, FrameAncestors) | 125 || equalIgnoringCase(name, FrameAncestors) |
| 122 || equalIgnoringCase(name, PluginTypes) | 126 || equalIgnoringCase(name, PluginTypes) |
| 123 || equalIgnoringCase(name, ReflectedXSS) | 127 || equalIgnoringCase(name, ReflectedXSS) |
| 124 || equalIgnoringCase(name, Referrer) | 128 || equalIgnoringCase(name, Referrer) |
| 125 || equalIgnoringCase(name, ManifestSrc) | 129 || equalIgnoringCase(name, ManifestSrc) |
| 126 || equalIgnoringCase(name, BlockAllMixedContent) | 130 || equalIgnoringCase(name, BlockAllMixedContent) |
| 127 || equalIgnoringCase(name, UpgradeInsecureRequests) | 131 || equalIgnoringCase(name, UpgradeInsecureRequests) |
| 128 || equalIgnoringCase(name, TreatAsPublicAddress)); | 132 || equalIgnoringCase(name, TreatAsPublicAddress) |
| 133 || equalIgnoringCase(name, RequireSRIFor)); | |
| 129 } | 134 } |
| 130 | 135 |
| 131 static UseCounter::Feature getUseCounterType(ContentSecurityPolicyHeaderType typ e) | 136 static UseCounter::Feature getUseCounterType(ContentSecurityPolicyHeaderType typ e) |
| 132 { | 137 { |
| 133 switch (type) { | 138 switch (type) { |
| 134 case ContentSecurityPolicyHeaderTypeEnforce: | 139 case ContentSecurityPolicyHeaderTypeEnforce: |
| 135 return UseCounter::ContentSecurityPolicy; | 140 return UseCounter::ContentSecurityPolicy; |
| 136 case ContentSecurityPolicyHeaderTypeReport: | 141 case ContentSecurityPolicyHeaderTypeReport: |
| 137 return UseCounter::ContentSecurityPolicyReportOnly; | 142 return UseCounter::ContentSecurityPolicyReportOnly; |
| 138 } | 143 } |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 553 bool ContentSecurityPolicy::allowScriptWithHash(const String& source, InlineType type) const | 558 bool ContentSecurityPolicy::allowScriptWithHash(const String& source, InlineType type) const |
| 554 { | 559 { |
| 555 return checkDigest<&CSPDirectiveList::allowScriptHash>(source, type, m_scrip tHashAlgorithmsUsed, m_policies); | 560 return checkDigest<&CSPDirectiveList::allowScriptHash>(source, type, m_scrip tHashAlgorithmsUsed, m_policies); |
| 556 } | 561 } |
| 557 | 562 |
| 558 bool ContentSecurityPolicy::allowStyleWithHash(const String& source, InlineType type) const | 563 bool ContentSecurityPolicy::allowStyleWithHash(const String& source, InlineType type) const |
| 559 { | 564 { |
| 560 return checkDigest<&CSPDirectiveList::allowStyleHash>(source, type, m_styleH ashAlgorithmsUsed, m_policies); | 565 return checkDigest<&CSPDirectiveList::allowStyleHash>(source, type, m_styleH ashAlgorithmsUsed, m_policies); |
| 561 } | 566 } |
| 562 | 567 |
| 563 bool ContentSecurityPolicy::allowRequest(WebURLRequest::RequestContext context, const KURL& url, const String& nonce, RedirectStatus redirectStatus, ReportingSt atus reportingStatus) const | 568 bool ContentSecurityPolicy::checkIntegrityMetadataPresence(WebURLRequest::Reques tContext context, const KURL& url, const IntegrityMetadataSet& integrityMetedata , ContentSecurityPolicy::ReportingStatus reportingStatus) const |
| 569 { | |
| 570 for (const auto& policy : m_policies) { | |
| 571 if (!policy->allowRequestWithoutMetadata(context, url, integrityMetedata , reportingStatus)) | |
|
Mike West
2016/06/10 09:25:15
I don't understand the naming choices here. Why is
Sergey Shekyan
2016/06/20 07:12:00
totally agree. Much clearer.
| |
| 572 return false; | |
| 573 } | |
| 574 return true; | |
| 575 } | |
| 576 | |
| 577 bool ContentSecurityPolicy::allowRequest(WebURLRequest::RequestContext context, const KURL& url, const String& nonce, const IntegrityMetadataSet& integrityMeted ata, RedirectStatus redirectStatus, ReportingStatus reportingStatus) const | |
|
Mike West
2016/06/10 09:25:15
Nit: s/Metedata/Metadata/
Sergey Shekyan
2016/06/20 07:12:00
Acknowledged.
| |
| 564 { | 578 { |
| 565 switch (context) { | 579 switch (context) { |
|
Mike West
2016/06/10 09:25:15
Rather than calling `checkIntegrityMetadataPresenc
Sergey Shekyan
2016/06/20 07:12:00
Acknowledged.
| |
| 566 case WebURLRequest::RequestContextAudio: | 580 case WebURLRequest::RequestContextAudio: |
| 567 case WebURLRequest::RequestContextTrack: | 581 case WebURLRequest::RequestContextTrack: |
| 568 case WebURLRequest::RequestContextVideo: | 582 case WebURLRequest::RequestContextVideo: |
| 569 return allowMediaFromSource(url, redirectStatus, reportingStatus); | 583 return allowMediaFromSource(url, redirectStatus, reportingStatus); |
| 570 case WebURLRequest::RequestContextBeacon: | 584 case WebURLRequest::RequestContextBeacon: |
| 571 case WebURLRequest::RequestContextEventSource: | 585 case WebURLRequest::RequestContextEventSource: |
| 572 case WebURLRequest::RequestContextFetch: | 586 case WebURLRequest::RequestContextFetch: |
| 573 case WebURLRequest::RequestContextXMLHttpRequest: | 587 case WebURLRequest::RequestContextXMLHttpRequest: |
| 574 return allowConnectToSource(url, redirectStatus, reportingStatus); | 588 return allowConnectToSource(url, redirectStatus, reportingStatus); |
| 575 case WebURLRequest::RequestContextEmbed: | 589 case WebURLRequest::RequestContextEmbed: |
| 576 case WebURLRequest::RequestContextObject: | 590 case WebURLRequest::RequestContextObject: |
| 577 return allowObjectFromSource(url, redirectStatus, reportingStatus); | 591 return allowObjectFromSource(url, redirectStatus, reportingStatus); |
| 578 case WebURLRequest::RequestContextFavicon: | 592 case WebURLRequest::RequestContextFavicon: |
| 579 case WebURLRequest::RequestContextImage: | 593 case WebURLRequest::RequestContextImage: |
| 580 case WebURLRequest::RequestContextImageSet: | 594 case WebURLRequest::RequestContextImageSet: |
| 581 return allowImageFromSource(url, redirectStatus, reportingStatus); | 595 return allowImageFromSource(url, redirectStatus, reportingStatus); |
| 582 case WebURLRequest::RequestContextFont: | 596 case WebURLRequest::RequestContextFont: |
| 583 return allowFontFromSource(url, redirectStatus, reportingStatus); | 597 return allowFontFromSource(url, redirectStatus, reportingStatus); |
| 584 case WebURLRequest::RequestContextForm: | 598 case WebURLRequest::RequestContextForm: |
| 585 return allowFormAction(url, redirectStatus, reportingStatus); | 599 return allowFormAction(url, redirectStatus, reportingStatus); |
| 586 case WebURLRequest::RequestContextFrame: | 600 case WebURLRequest::RequestContextFrame: |
| 587 case WebURLRequest::RequestContextIframe: | 601 case WebURLRequest::RequestContextIframe: |
| 588 return allowChildFrameFromSource(url, redirectStatus, reportingStatus); | 602 return allowChildFrameFromSource(url, redirectStatus, reportingStatus); |
| 589 case WebURLRequest::RequestContextImport: | 603 case WebURLRequest::RequestContextImport: |
| 590 case WebURLRequest::RequestContextScript: | 604 case WebURLRequest::RequestContextScript: |
| 605 return checkIntegrityMetadataPresence(WebURLRequest::RequestContextScrip t, url, integrityMetedata, reportingStatus) | |
| 606 && allowScriptFromSource(url, nonce, redirectStatus, reportingStatus ); | |
|
Mike West
2016/06/10 09:25:15
Please add tests for the kinds of script creation
| |
| 591 case WebURLRequest::RequestContextXSLT: | 607 case WebURLRequest::RequestContextXSLT: |
| 592 return allowScriptFromSource(url, nonce, redirectStatus, reportingStatus ); | 608 return allowScriptFromSource(url, nonce, redirectStatus, reportingStatus ); |
| 593 case WebURLRequest::RequestContextManifest: | 609 case WebURLRequest::RequestContextManifest: |
| 594 return allowManifestFromSource(url, redirectStatus, reportingStatus); | 610 return allowManifestFromSource(url, redirectStatus, reportingStatus); |
| 595 case WebURLRequest::RequestContextServiceWorker: | 611 case WebURLRequest::RequestContextServiceWorker: |
| 596 case WebURLRequest::RequestContextSharedWorker: | 612 case WebURLRequest::RequestContextSharedWorker: |
| 597 case WebURLRequest::RequestContextWorker: | 613 case WebURLRequest::RequestContextWorker: |
| 598 return allowWorkerContextFromSource(url, redirectStatus, reportingStatus ); | 614 return allowWorkerContextFromSource(url, redirectStatus, reportingStatus ); |
|
Mike West
2016/06/10 09:25:15
Here too, along with layout tests for worker creat
| |
| 599 case WebURLRequest::RequestContextStyle: | 615 case WebURLRequest::RequestContextStyle: |
| 600 return allowStyleFromSource(url, nonce, redirectStatus, reportingStatus) ; | 616 return checkIntegrityMetadataPresence(WebURLRequest::RequestContextStyle , url, integrityMetedata, reportingStatus) |
| 617 && allowStyleFromSource(url, nonce, redirectStatus, reportingStatus) ; | |
| 601 case WebURLRequest::RequestContextCSPReport: | 618 case WebURLRequest::RequestContextCSPReport: |
| 602 case WebURLRequest::RequestContextDownload: | 619 case WebURLRequest::RequestContextDownload: |
| 603 case WebURLRequest::RequestContextHyperlink: | 620 case WebURLRequest::RequestContextHyperlink: |
| 604 case WebURLRequest::RequestContextInternal: | 621 case WebURLRequest::RequestContextInternal: |
| 605 case WebURLRequest::RequestContextLocation: | 622 case WebURLRequest::RequestContextLocation: |
| 606 case WebURLRequest::RequestContextPing: | 623 case WebURLRequest::RequestContextPing: |
| 607 case WebURLRequest::RequestContextPlugin: | 624 case WebURLRequest::RequestContextPlugin: |
| 608 case WebURLRequest::RequestContextPrefetch: | 625 case WebURLRequest::RequestContextPrefetch: |
| 609 case WebURLRequest::RequestContextSubresource: | 626 case WebURLRequest::RequestContextSubresource: |
| 610 case WebURLRequest::RequestContextUnspecified: | 627 case WebURLRequest::RequestContextUnspecified: |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 989 void ContentSecurityPolicy::reportInvalidSandboxFlags(const String& invalidFlags ) | 1006 void ContentSecurityPolicy::reportInvalidSandboxFlags(const String& invalidFlags ) |
| 990 { | 1007 { |
| 991 logToConsole("Error while parsing the 'sandbox' Content Security Policy dire ctive: " + invalidFlags); | 1008 logToConsole("Error while parsing the 'sandbox' Content Security Policy dire ctive: " + invalidFlags); |
| 992 } | 1009 } |
| 993 | 1010 |
| 994 void ContentSecurityPolicy::reportInvalidReflectedXSS(const String& invalidValue ) | 1011 void ContentSecurityPolicy::reportInvalidReflectedXSS(const String& invalidValue ) |
| 995 { | 1012 { |
| 996 logToConsole("The 'reflected-xss' Content Security Policy directive has the invalid value \"" + invalidValue + "\". Valid values are \"allow\", \"filter\", and \"block\"."); | 1013 logToConsole("The 'reflected-xss' Content Security Policy directive has the invalid value \"" + invalidValue + "\". Valid values are \"allow\", \"filter\", and \"block\"."); |
| 997 } | 1014 } |
| 998 | 1015 |
| 1016 void ContentSecurityPolicy::reportInvalidRequireSRIForTokens(const String& inval idTokens) | |
| 1017 { | |
| 1018 logToConsole("Error while parsing the 'require-sri-for' Content Security Pol icy directive: " + invalidTokens); | |
| 1019 } | |
| 1020 | |
| 999 void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(const String& d irectiveName, const String& value) | 1021 void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(const String& d irectiveName, const String& value) |
| 1000 { | 1022 { |
| 1001 String message = "The value for Content Security Policy directive '" + direc tiveName + "' contains an invalid character: '" + value + "'. Non-whitespace cha racters outside ASCII 0x21-0x7E must be percent-encoded, as described in RFC 398 6, section 2.1: http://tools.ietf.org/html/rfc3986#section-2.1."; | 1023 String message = "The value for Content Security Policy directive '" + direc tiveName + "' contains an invalid character: '" + value + "'. Non-whitespace cha racters outside ASCII 0x21-0x7E must be percent-encoded, as described in RFC 398 6, section 2.1: http://tools.ietf.org/html/rfc3986#section-2.1."; |
| 1002 logToConsole(message); | 1024 logToConsole(message); |
| 1003 } | 1025 } |
| 1004 | 1026 |
| 1005 void ContentSecurityPolicy::reportInvalidPathCharacter(const String& directiveNa me, const String& value, const char invalidChar) | 1027 void ContentSecurityPolicy::reportInvalidPathCharacter(const String& directiveNa me, const String& value, const char invalidChar) |
| 1006 { | 1028 { |
| 1007 ASSERT(invalidChar == '#' || invalidChar == '?'); | 1029 ASSERT(invalidChar == '#' || invalidChar == '?'); |
| 1008 | 1030 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1096 // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report. | 1118 // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report. |
| 1097 return !m_violationReportsSent.contains(report.impl()->hash()); | 1119 return !m_violationReportsSent.contains(report.impl()->hash()); |
| 1098 } | 1120 } |
| 1099 | 1121 |
| 1100 void ContentSecurityPolicy::didSendViolationReport(const String& report) | 1122 void ContentSecurityPolicy::didSendViolationReport(const String& report) |
| 1101 { | 1123 { |
| 1102 m_violationReportsSent.add(report.impl()->hash()); | 1124 m_violationReportsSent.add(report.impl()->hash()); |
| 1103 } | 1125 } |
| 1104 | 1126 |
| 1105 } // namespace blink | 1127 } // namespace blink |
| OLD | NEW |