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::allowRequestWithoutIntegrity(WebURLRequest::RequestC
ontext context, const KURL& url, RedirectStatus redirectStatus, ContentSecurityP
olicy::ReportingStatus reportingStatus) const |
564 { | 569 { |
| 570 for (const auto& policy : m_policies) { |
| 571 if (!policy->allowRequestWithoutIntegrity(context, url, redirectStatus,
reportingStatus)) |
| 572 return false; |
| 573 } |
| 574 return true; |
| 575 } |
| 576 |
| 577 bool ContentSecurityPolicy::allowRequest(WebURLRequest::RequestContext context,
const KURL& url, const String& nonce, const IntegrityMetadataSet& integrityMetad
ata, RedirectStatus redirectStatus, ReportingStatus reportingStatus) const |
| 578 { |
| 579 if (integrityMetadata.isEmpty() |
| 580 && !allowRequestWithoutIntegrity(context, url, redirectStatus, reporting
Status)) |
| 581 return false; |
| 582 |
565 switch (context) { | 583 switch (context) { |
566 case WebURLRequest::RequestContextAudio: | 584 case WebURLRequest::RequestContextAudio: |
567 case WebURLRequest::RequestContextTrack: | 585 case WebURLRequest::RequestContextTrack: |
568 case WebURLRequest::RequestContextVideo: | 586 case WebURLRequest::RequestContextVideo: |
569 return allowMediaFromSource(url, redirectStatus, reportingStatus); | 587 return allowMediaFromSource(url, redirectStatus, reportingStatus); |
570 case WebURLRequest::RequestContextBeacon: | 588 case WebURLRequest::RequestContextBeacon: |
571 case WebURLRequest::RequestContextEventSource: | 589 case WebURLRequest::RequestContextEventSource: |
572 case WebURLRequest::RequestContextFetch: | 590 case WebURLRequest::RequestContextFetch: |
573 case WebURLRequest::RequestContextXMLHttpRequest: | 591 case WebURLRequest::RequestContextXMLHttpRequest: |
574 return allowConnectToSource(url, redirectStatus, reportingStatus); | 592 return allowConnectToSource(url, redirectStatus, reportingStatus); |
575 case WebURLRequest::RequestContextEmbed: | 593 case WebURLRequest::RequestContextEmbed: |
576 case WebURLRequest::RequestContextObject: | 594 case WebURLRequest::RequestContextObject: |
577 return allowObjectFromSource(url, redirectStatus, reportingStatus); | 595 return allowObjectFromSource(url, redirectStatus, reportingStatus); |
578 case WebURLRequest::RequestContextFavicon: | 596 case WebURLRequest::RequestContextFavicon: |
579 case WebURLRequest::RequestContextImage: | 597 case WebURLRequest::RequestContextImage: |
580 case WebURLRequest::RequestContextImageSet: | 598 case WebURLRequest::RequestContextImageSet: |
581 return allowImageFromSource(url, redirectStatus, reportingStatus); | 599 return allowImageFromSource(url, redirectStatus, reportingStatus); |
582 case WebURLRequest::RequestContextFont: | 600 case WebURLRequest::RequestContextFont: |
583 return allowFontFromSource(url, redirectStatus, reportingStatus); | 601 return allowFontFromSource(url, redirectStatus, reportingStatus); |
584 case WebURLRequest::RequestContextForm: | 602 case WebURLRequest::RequestContextForm: |
585 return allowFormAction(url, redirectStatus, reportingStatus); | 603 return allowFormAction(url, redirectStatus, reportingStatus); |
586 case WebURLRequest::RequestContextFrame: | 604 case WebURLRequest::RequestContextFrame: |
587 case WebURLRequest::RequestContextIframe: | 605 case WebURLRequest::RequestContextIframe: |
588 return allowChildFrameFromSource(url, redirectStatus, reportingStatus); | 606 return allowChildFrameFromSource(url, redirectStatus, reportingStatus); |
589 case WebURLRequest::RequestContextImport: | 607 case WebURLRequest::RequestContextImport: |
590 case WebURLRequest::RequestContextScript: | 608 case WebURLRequest::RequestContextScript: |
| 609 return allowScriptFromSource(url, nonce, redirectStatus, reportingStatus
); |
591 case WebURLRequest::RequestContextXSLT: | 610 case WebURLRequest::RequestContextXSLT: |
592 return allowScriptFromSource(url, nonce, redirectStatus, reportingStatus
); | 611 return allowScriptFromSource(url, nonce, redirectStatus, reportingStatus
); |
593 case WebURLRequest::RequestContextManifest: | 612 case WebURLRequest::RequestContextManifest: |
594 return allowManifestFromSource(url, redirectStatus, reportingStatus); | 613 return allowManifestFromSource(url, redirectStatus, reportingStatus); |
595 case WebURLRequest::RequestContextServiceWorker: | 614 case WebURLRequest::RequestContextServiceWorker: |
596 case WebURLRequest::RequestContextSharedWorker: | 615 case WebURLRequest::RequestContextSharedWorker: |
597 case WebURLRequest::RequestContextWorker: | 616 case WebURLRequest::RequestContextWorker: |
598 return allowWorkerContextFromSource(url, redirectStatus, reportingStatus
); | 617 return allowWorkerContextFromSource(url, redirectStatus, reportingStatus
); |
599 case WebURLRequest::RequestContextStyle: | 618 case WebURLRequest::RequestContextStyle: |
600 return allowStyleFromSource(url, nonce, redirectStatus, reportingStatus)
; | 619 return allowStyleFromSource(url, nonce, redirectStatus, reportingStatus)
; |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
989 void ContentSecurityPolicy::reportInvalidSandboxFlags(const String& invalidFlags
) | 1008 void ContentSecurityPolicy::reportInvalidSandboxFlags(const String& invalidFlags
) |
990 { | 1009 { |
991 logToConsole("Error while parsing the 'sandbox' Content Security Policy dire
ctive: " + invalidFlags); | 1010 logToConsole("Error while parsing the 'sandbox' Content Security Policy dire
ctive: " + invalidFlags); |
992 } | 1011 } |
993 | 1012 |
994 void ContentSecurityPolicy::reportInvalidReflectedXSS(const String& invalidValue
) | 1013 void ContentSecurityPolicy::reportInvalidReflectedXSS(const String& invalidValue
) |
995 { | 1014 { |
996 logToConsole("The 'reflected-xss' Content Security Policy directive has the
invalid value \"" + invalidValue + "\". Valid values are \"allow\", \"filter\",
and \"block\"."); | 1015 logToConsole("The 'reflected-xss' Content Security Policy directive has the
invalid value \"" + invalidValue + "\". Valid values are \"allow\", \"filter\",
and \"block\"."); |
997 } | 1016 } |
998 | 1017 |
| 1018 void ContentSecurityPolicy::reportInvalidRequireSRIForTokens(const String& inval
idTokens) |
| 1019 { |
| 1020 logToConsole("Error while parsing the 'require-sri-for' Content Security Pol
icy directive: " + invalidTokens); |
| 1021 } |
| 1022 |
999 void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(const String& d
irectiveName, const String& value) | 1023 void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(const String& d
irectiveName, const String& value) |
1000 { | 1024 { |
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."; | 1025 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); | 1026 logToConsole(message); |
1003 } | 1027 } |
1004 | 1028 |
1005 void ContentSecurityPolicy::reportInvalidPathCharacter(const String& directiveNa
me, const String& value, const char invalidChar) | 1029 void ContentSecurityPolicy::reportInvalidPathCharacter(const String& directiveNa
me, const String& value, const char invalidChar) |
1006 { | 1030 { |
1007 ASSERT(invalidChar == '#' || invalidChar == '?'); | 1031 ASSERT(invalidChar == '#' || invalidChar == '?'); |
1008 | 1032 |
(...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. | 1120 // 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()); | 1121 return !m_violationReportsSent.contains(report.impl()->hash()); |
1098 } | 1122 } |
1099 | 1123 |
1100 void ContentSecurityPolicy::didSendViolationReport(const String& report) | 1124 void ContentSecurityPolicy::didSendViolationReport(const String& report) |
1101 { | 1125 { |
1102 m_violationReportsSent.add(report.impl()->hash()); | 1126 m_violationReportsSent.add(report.impl()->hash()); |
1103 } | 1127 } |
1104 | 1128 |
1105 } // namespace blink | 1129 } // namespace blink |
OLD | NEW |