| 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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 const char ContentSecurityPolicy::Referrer[] = "referrer"; | 86 const char ContentSecurityPolicy::Referrer[] = "referrer"; |
| 87 | 87 |
| 88 // Manifest Directives | 88 // Manifest Directives |
| 89 // https://w3c.github.io/manifest/#content-security-policy | 89 // https://w3c.github.io/manifest/#content-security-policy |
| 90 const char ContentSecurityPolicy::ManifestSrc[] = "manifest-src"; | 90 const char ContentSecurityPolicy::ManifestSrc[] = "manifest-src"; |
| 91 | 91 |
| 92 // Mixed Content Directive | 92 // Mixed Content Directive |
| 93 // https://w3c.github.io/webappsec/specs/mixedcontent/#strict-mode | 93 // https://w3c.github.io/webappsec/specs/mixedcontent/#strict-mode |
| 94 const char ContentSecurityPolicy::BlockAllMixedContent[] = "block-all-mixed-cont
ent"; | 94 const char ContentSecurityPolicy::BlockAllMixedContent[] = "block-all-mixed-cont
ent"; |
| 95 | 95 |
| 96 // https://w3c.github.io/webappsec/specs/upgrade/ |
| 97 const char ContentSecurityPolicy::UpgradeInsecureRequests[] = "upgrade-insecure-
requests"; |
| 98 |
| 96 bool ContentSecurityPolicy::isDirectiveName(const String& name) | 99 bool ContentSecurityPolicy::isDirectiveName(const String& name) |
| 97 { | 100 { |
| 98 return (equalIgnoringCase(name, ConnectSrc) | 101 return (equalIgnoringCase(name, ConnectSrc) |
| 99 || equalIgnoringCase(name, DefaultSrc) | 102 || equalIgnoringCase(name, DefaultSrc) |
| 100 || equalIgnoringCase(name, FontSrc) | 103 || equalIgnoringCase(name, FontSrc) |
| 101 || equalIgnoringCase(name, FrameSrc) | 104 || equalIgnoringCase(name, FrameSrc) |
| 102 || equalIgnoringCase(name, ImgSrc) | 105 || equalIgnoringCase(name, ImgSrc) |
| 103 || equalIgnoringCase(name, MediaSrc) | 106 || equalIgnoringCase(name, MediaSrc) |
| 104 || equalIgnoringCase(name, ObjectSrc) | 107 || equalIgnoringCase(name, ObjectSrc) |
| 105 || equalIgnoringCase(name, ReportURI) | 108 || equalIgnoringCase(name, ReportURI) |
| 106 || equalIgnoringCase(name, Sandbox) | 109 || equalIgnoringCase(name, Sandbox) |
| 107 || equalIgnoringCase(name, ScriptSrc) | 110 || equalIgnoringCase(name, ScriptSrc) |
| 108 || equalIgnoringCase(name, StyleSrc) | 111 || equalIgnoringCase(name, StyleSrc) |
| 109 || equalIgnoringCase(name, BaseURI) | 112 || equalIgnoringCase(name, BaseURI) |
| 110 || equalIgnoringCase(name, ChildSrc) | 113 || equalIgnoringCase(name, ChildSrc) |
| 111 || equalIgnoringCase(name, FormAction) | 114 || equalIgnoringCase(name, FormAction) |
| 112 || equalIgnoringCase(name, FrameAncestors) | 115 || equalIgnoringCase(name, FrameAncestors) |
| 113 || equalIgnoringCase(name, PluginTypes) | 116 || equalIgnoringCase(name, PluginTypes) |
| 114 || equalIgnoringCase(name, ReflectedXSS) | 117 || equalIgnoringCase(name, ReflectedXSS) |
| 115 || equalIgnoringCase(name, Referrer) | 118 || equalIgnoringCase(name, Referrer) |
| 116 || equalIgnoringCase(name, ManifestSrc) | 119 || equalIgnoringCase(name, ManifestSrc) |
| 117 || equalIgnoringCase(name, BlockAllMixedContent)); | 120 || equalIgnoringCase(name, BlockAllMixedContent) |
| 121 || equalIgnoringCase(name, UpgradeInsecureRequests)); |
| 118 } | 122 } |
| 119 | 123 |
| 120 static UseCounter::Feature getUseCounterType(ContentSecurityPolicyHeaderType typ
e) | 124 static UseCounter::Feature getUseCounterType(ContentSecurityPolicyHeaderType typ
e) |
| 121 { | 125 { |
| 122 switch (type) { | 126 switch (type) { |
| 123 case ContentSecurityPolicyHeaderTypeEnforce: | 127 case ContentSecurityPolicyHeaderTypeEnforce: |
| 124 return UseCounter::ContentSecurityPolicy; | 128 return UseCounter::ContentSecurityPolicy; |
| 125 case ContentSecurityPolicyHeaderTypeReport: | 129 case ContentSecurityPolicyHeaderTypeReport: |
| 126 return UseCounter::ContentSecurityPolicyReportOnly; | 130 return UseCounter::ContentSecurityPolicyReportOnly; |
| 127 } | 131 } |
| 128 ASSERT_NOT_REACHED(); | 132 ASSERT_NOT_REACHED(); |
| 129 return UseCounter::NumberOfFeatures; | 133 return UseCounter::NumberOfFeatures; |
| 130 } | 134 } |
| 131 | 135 |
| 132 static ReferrerPolicy mergeReferrerPolicies(ReferrerPolicy a, ReferrerPolicy b) | 136 static ReferrerPolicy mergeReferrerPolicies(ReferrerPolicy a, ReferrerPolicy b) |
| 133 { | 137 { |
| 134 if (a != b) | 138 if (a != b) |
| 135 return ReferrerPolicyNever; | 139 return ReferrerPolicyNever; |
| 136 return a; | 140 return a; |
| 137 } | 141 } |
| 138 | 142 |
| 139 ContentSecurityPolicy::ContentSecurityPolicy() | 143 ContentSecurityPolicy::ContentSecurityPolicy() |
| 140 : m_executionContext(nullptr) | 144 : m_executionContext(nullptr) |
| 141 , m_overrideInlineStyleAllowed(false) | 145 , m_overrideInlineStyleAllowed(false) |
| 142 , m_scriptHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) | 146 , m_scriptHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) |
| 143 , m_styleHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) | 147 , m_styleHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) |
| 144 , m_sandboxMask(0) | 148 , m_sandboxMask(0) |
| 145 , m_enforceStrictMixedContentChecking(false) | 149 , m_enforceStrictMixedContentChecking(false) |
| 146 , m_referrerPolicy(ReferrerPolicyDefault) | 150 , m_referrerPolicy(ReferrerPolicyDefault) |
| 151 , m_insecureContentPolicy(SecurityContext::InsecureContentDoNotUpgrade) |
| 147 { | 152 { |
| 148 } | 153 } |
| 149 | 154 |
| 150 void ContentSecurityPolicy::bindToExecutionContext(ExecutionContext* executionCo
ntext) | 155 void ContentSecurityPolicy::bindToExecutionContext(ExecutionContext* executionCo
ntext) |
| 151 { | 156 { |
| 152 m_executionContext = executionContext; | 157 m_executionContext = executionContext; |
| 153 applyPolicySideEffectsToExecutionContext(); | 158 applyPolicySideEffectsToExecutionContext(); |
| 154 } | 159 } |
| 155 | 160 |
| 156 void ContentSecurityPolicy::applyPolicySideEffectsToExecutionContext() | 161 void ContentSecurityPolicy::applyPolicySideEffectsToExecutionContext() |
| 157 { | 162 { |
| 158 ASSERT(m_executionContext); | 163 ASSERT(m_executionContext); |
| 159 // Ensure that 'self' processes correctly. | 164 // Ensure that 'self' processes correctly. |
| 160 m_selfProtocol = securityOrigin()->protocol(); | 165 m_selfProtocol = securityOrigin()->protocol(); |
| 161 m_selfSource = adoptPtr(new CSPSource(this, m_selfProtocol, securityOrigin()
->host(), securityOrigin()->port(), String(), CSPSource::NoWildcard, CSPSource::
NoWildcard)); | 166 m_selfSource = adoptPtr(new CSPSource(this, m_selfProtocol, securityOrigin()
->host(), securityOrigin()->port(), String(), CSPSource::NoWildcard, CSPSource::
NoWildcard)); |
| 162 | 167 |
| 163 // If we're in a Document, set the referrer policy, mixed content checking,
and sandbox | 168 // If we're in a Document, set the referrer policy, mixed content checking,
and sandbox |
| 164 // flags, then dump all the parsing error messages, then poke at histograms. | 169 // flags, then dump all the parsing error messages, then poke at histograms. |
| 165 if (Document* document = this->document()) { | 170 if (Document* document = this->document()) { |
| 166 if (m_sandboxMask != SandboxNone) { | 171 if (m_sandboxMask != SandboxNone) { |
| 167 UseCounter::count(document, UseCounter::SandboxViaCSP); | 172 UseCounter::count(document, UseCounter::SandboxViaCSP); |
| 168 document->enforceSandboxFlags(m_sandboxMask); | 173 document->enforceSandboxFlags(m_sandboxMask); |
| 169 } | 174 } |
| 170 if (m_enforceStrictMixedContentChecking) | 175 if (m_enforceStrictMixedContentChecking) |
| 171 document->enforceStrictMixedContentChecking(); | 176 document->enforceStrictMixedContentChecking(); |
| 172 if (didSetReferrerPolicy()) | 177 if (didSetReferrerPolicy()) |
| 173 document->setReferrerPolicy(m_referrerPolicy); | 178 document->setReferrerPolicy(m_referrerPolicy); |
| 179 if (m_insecureContentPolicy > document->insecureContentPolicy()) |
| 180 document->setInsecureContentPolicy(m_insecureContentPolicy); |
| 174 | 181 |
| 175 for (const auto& consoleMessage : m_consoleMessages) | 182 for (const auto& consoleMessage : m_consoleMessages) |
| 176 m_executionContext->addConsoleMessage(consoleMessage); | 183 m_executionContext->addConsoleMessage(consoleMessage); |
| 177 m_consoleMessages.clear(); | 184 m_consoleMessages.clear(); |
| 178 | 185 |
| 179 for (const auto& policy : m_policies) | 186 for (const auto& policy : m_policies) |
| 180 UseCounter::count(*document, getUseCounterType(policy->headerType())
); | 187 UseCounter::count(*document, getUseCounterType(policy->headerType())
); |
| 181 } | 188 } |
| 182 | 189 |
| 183 // We disable 'eval()' even in the case of report-only policies, and rely on
the check in the | 190 // We disable 'eval()' even in the case of report-only policies, and rely on
the check in the |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 void ContentSecurityPolicy::enforceSandboxFlags(SandboxFlags mask) | 626 void ContentSecurityPolicy::enforceSandboxFlags(SandboxFlags mask) |
| 620 { | 627 { |
| 621 m_sandboxMask |= mask; | 628 m_sandboxMask |= mask; |
| 622 } | 629 } |
| 623 | 630 |
| 624 void ContentSecurityPolicy::enforceStrictMixedContentChecking() | 631 void ContentSecurityPolicy::enforceStrictMixedContentChecking() |
| 625 { | 632 { |
| 626 m_enforceStrictMixedContentChecking = true; | 633 m_enforceStrictMixedContentChecking = true; |
| 627 } | 634 } |
| 628 | 635 |
| 636 void ContentSecurityPolicy::setInsecureContentPolicy(SecurityContext::InsecureCo
ntentPolicy policy) |
| 637 { |
| 638 if (policy > m_insecureContentPolicy) |
| 639 m_insecureContentPolicy = policy; |
| 640 } |
| 641 |
| 629 static String stripURLForUseInReport(Document* document, const KURL& url) | 642 static String stripURLForUseInReport(Document* document, const KURL& url) |
| 630 { | 643 { |
| 631 if (!url.isValid()) | 644 if (!url.isValid()) |
| 632 return String(); | 645 return String(); |
| 633 if (!url.isHierarchical() || url.protocolIs("file")) | 646 if (!url.isHierarchical() || url.protocolIs("file")) |
| 634 return url.protocol(); | 647 return url.protocol(); |
| 635 return document->securityOrigin()->canRequest(url) ? url.strippedForUseAsRef
errer() : SecurityOrigin::create(url)->toString(); | 648 return document->securityOrigin()->canRequest(url) ? url.strippedForUseAsRef
errer() : SecurityOrigin::create(url)->toString(); |
| 636 } | 649 } |
| 637 | 650 |
| 638 static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventI
nit& init, Document* document, const String& directiveText, const String& effect
iveDirective, const KURL& blockedURL, const String& header) | 651 static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventI
nit& init, Document* document, const String& directiveText, const String& effect
iveDirective, const KURL& blockedURL, const String& header) |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 // Collisions have no security impact, so we can save space by storing only
the string's hash rather than the whole report. | 919 // Collisions have no security impact, so we can save space by storing only
the string's hash rather than the whole report. |
| 907 return !m_violationReportsSent.contains(report.impl()->hash()); | 920 return !m_violationReportsSent.contains(report.impl()->hash()); |
| 908 } | 921 } |
| 909 | 922 |
| 910 void ContentSecurityPolicy::didSendViolationReport(const String& report) | 923 void ContentSecurityPolicy::didSendViolationReport(const String& report) |
| 911 { | 924 { |
| 912 m_violationReportsSent.add(report.impl()->hash()); | 925 m_violationReportsSent.add(report.impl()->hash()); |
| 913 } | 926 } |
| 914 | 927 |
| 915 } // namespace blink | 928 } // namespace blink |
| OLD | NEW |