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" |
| 11 #include "core/frame/Deprecation.h" |
11 #include "core/frame/LocalFrame.h" | 12 #include "core/frame/LocalFrame.h" |
12 #include "core/frame/UseCounter.h" | 13 #include "core/frame/UseCounter.h" |
13 #include "core/html/HTMLScriptElement.h" | 14 #include "core/html/HTMLScriptElement.h" |
14 #include "core/inspector/ConsoleMessage.h" | 15 #include "core/inspector/ConsoleMessage.h" |
15 #include "platform/Crypto.h" | 16 #include "platform/Crypto.h" |
16 #include "platform/RuntimeEnabledFeatures.h" | 17 #include "platform/RuntimeEnabledFeatures.h" |
17 #include "platform/network/ContentSecurityPolicyParsers.h" | 18 #include "platform/network/ContentSecurityPolicyParsers.h" |
18 #include "platform/weborigin/KURL.h" | 19 #include "platform/weborigin/KURL.h" |
19 #include "wtf/text/Base64.h" | 20 #include "wtf/text/Base64.h" |
20 #include "wtf/text/ParsingUtilities.h" | 21 #include "wtf/text/ParsingUtilities.h" |
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 UseCounter::BaseWouldBeBlockedByDefaultSrc); | 786 UseCounter::BaseWouldBeBlockedByDefaultSrc); |
786 } | 787 } |
787 | 788 |
788 return result; | 789 return result; |
789 } | 790 } |
790 | 791 |
791 bool CSPDirectiveList::allowWorkerFromSource( | 792 bool CSPDirectiveList::allowWorkerFromSource( |
792 const KURL& url, | 793 const KURL& url, |
793 ResourceRequest::RedirectStatus redirectStatus, | 794 ResourceRequest::RedirectStatus redirectStatus, |
794 SecurityViolationReportingPolicy reportingPolicy) const { | 795 SecurityViolationReportingPolicy reportingPolicy) const { |
795 // 'worker-src' overrides 'child-src', which overrides the default | |
796 // sources. So, we do this nested set of calls to 'operativeDirective()' to | 796 // sources. So, we do this nested set of calls to 'operativeDirective()' to |
797 // grab 'worker-src' if it exists, 'child-src' if it doesn't, and 'defaut-src' | 797 // grab 'worker-src' if it exists, 'script-src' if it doesn't, and |
798 // if neither are available. | 798 // 'defaut-src' if neither are available. |
799 SourceListDirective* whichDirective = operativeDirective( | 799 SourceListDirective* workerSrc = operativeDirective( |
800 m_workerSrc.get(), operativeDirective(m_childSrc.get())); | 800 m_workerSrc.get(), operativeDirective(m_scriptSrc.get())); |
| 801 |
| 802 // In CSP2, workers are controlled via 'child-src'. CSP3 moves them to |
| 803 // 'script-src'. In order to avoid breaking sites that allowed workers via |
| 804 // 'child-src' that would have been blocked via 'script-src', we'll |
| 805 // temporarily check whether a worker blocked via 'script-src' would have been |
| 806 // allowed under 'child-src'. If the new 'worker-src' directive is present, |
| 807 // however, we'll assume that the developer knows what they're asking for, and |
| 808 // skip the extra fallback. |
| 809 // |
| 810 // That is, we'll block 'https://example.com/worker' given the policy |
| 811 // "worker-src 'none'", "worker-src 'none'; child-src https://example.com", |
| 812 // but we'll allow it given the policy |
| 813 // "script-src https://not-example.com; child-src https://example.com" |
| 814 // (because 'child-src' allows it) or "child-src https://not-example.com" |
| 815 // (because the absent 'script-src' allows it). |
| 816 // |
| 817 // TODO(mkwst): Remove this once other vendors follow suit. |
| 818 // https://crbug.com/662930 |
| 819 if (!checkSource(workerSrc, url, redirectStatus) && !m_workerSrc && |
| 820 m_childSrc && checkSource(m_childSrc, url, redirectStatus)) { |
| 821 Deprecation::countDeprecation( |
| 822 m_policy->document(), |
| 823 UseCounter::ChildSrcAllowedWorkerThatScriptSrcBlocked); |
| 824 return true; |
| 825 } |
801 | 826 |
802 return reportingPolicy == SecurityViolationReportingPolicy::Report | 827 return reportingPolicy == SecurityViolationReportingPolicy::Report |
803 ? checkSourceAndReportViolation( | 828 ? checkSourceAndReportViolation( |
804 whichDirective, url, | 829 workerSrc, url, |
805 ContentSecurityPolicy::DirectiveType::WorkerSrc, | 830 ContentSecurityPolicy::DirectiveType::WorkerSrc, |
806 redirectStatus) | 831 redirectStatus) |
807 : checkSource(whichDirective, url, redirectStatus); | 832 : checkSource(workerSrc, url, redirectStatus); |
808 } | 833 } |
809 | 834 |
810 bool CSPDirectiveList::allowAncestors( | 835 bool CSPDirectiveList::allowAncestors( |
811 LocalFrame* frame, | 836 LocalFrame* frame, |
812 const KURL& url, | 837 const KURL& url, |
813 SecurityViolationReportingPolicy reportingPolicy) const { | 838 SecurityViolationReportingPolicy reportingPolicy) const { |
814 return reportingPolicy == SecurityViolationReportingPolicy::Report | 839 return reportingPolicy == SecurityViolationReportingPolicy::Report |
815 ? checkAncestorsAndReportViolation(m_frameAncestors.get(), frame, | 840 ? checkAncestorsAndReportViolation(m_frameAncestors.get(), frame, |
816 url) | 841 url) |
817 : checkAncestors(m_frameAncestors.get(), frame); | 842 : checkAncestors(m_frameAncestors.get(), frame); |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1154 } else if (type == ContentSecurityPolicy::DirectiveType::ConnectSrc) { | 1179 } else if (type == ContentSecurityPolicy::DirectiveType::ConnectSrc) { |
1155 setCSPDirective<SourceListDirective>(name, value, m_connectSrc); | 1180 setCSPDirective<SourceListDirective>(name, value, m_connectSrc); |
1156 } else if (type == ContentSecurityPolicy::DirectiveType::Sandbox) { | 1181 } else if (type == ContentSecurityPolicy::DirectiveType::Sandbox) { |
1157 applySandboxPolicy(name, value); | 1182 applySandboxPolicy(name, value); |
1158 } else if (type == ContentSecurityPolicy::DirectiveType::ReportURI) { | 1183 } else if (type == ContentSecurityPolicy::DirectiveType::ReportURI) { |
1159 parseReportURI(name, value); | 1184 parseReportURI(name, value); |
1160 } else if (type == ContentSecurityPolicy::DirectiveType::BaseURI) { | 1185 } else if (type == ContentSecurityPolicy::DirectiveType::BaseURI) { |
1161 setCSPDirective<SourceListDirective>(name, value, m_baseURI); | 1186 setCSPDirective<SourceListDirective>(name, value, m_baseURI); |
1162 } else if (type == ContentSecurityPolicy::DirectiveType::ChildSrc) { | 1187 } else if (type == ContentSecurityPolicy::DirectiveType::ChildSrc) { |
1163 setCSPDirective<SourceListDirective>(name, value, m_childSrc); | 1188 setCSPDirective<SourceListDirective>(name, value, m_childSrc); |
1164 } else if (type == ContentSecurityPolicy::DirectiveType::WorkerSrc && | 1189 } else if (type == ContentSecurityPolicy::DirectiveType::WorkerSrc) { |
1165 m_policy->experimentalFeaturesEnabled()) { | |
1166 setCSPDirective<SourceListDirective>(name, value, m_workerSrc); | 1190 setCSPDirective<SourceListDirective>(name, value, m_workerSrc); |
1167 } else if (type == ContentSecurityPolicy::DirectiveType::FormAction) { | 1191 } else if (type == ContentSecurityPolicy::DirectiveType::FormAction) { |
1168 setCSPDirective<SourceListDirective>(name, value, m_formAction); | 1192 setCSPDirective<SourceListDirective>(name, value, m_formAction); |
1169 } else if (type == ContentSecurityPolicy::DirectiveType::PluginTypes) { | 1193 } else if (type == ContentSecurityPolicy::DirectiveType::PluginTypes) { |
1170 setCSPDirective<MediaListDirective>(name, value, m_pluginTypes); | 1194 setCSPDirective<MediaListDirective>(name, value, m_pluginTypes); |
1171 } else if (type == | 1195 } else if (type == |
1172 ContentSecurityPolicy::DirectiveType::UpgradeInsecureRequests) { | 1196 ContentSecurityPolicy::DirectiveType::UpgradeInsecureRequests) { |
1173 enableInsecureRequestsUpgrade(name, value); | 1197 enableInsecureRequestsUpgrade(name, value); |
1174 } else if (type == | 1198 } else if (type == |
1175 ContentSecurityPolicy::DirectiveType::BlockAllMixedContent) { | 1199 ContentSecurityPolicy::DirectiveType::BlockAllMixedContent) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1211 case ContentSecurityPolicy::DirectiveType::ManifestSrc: | 1235 case ContentSecurityPolicy::DirectiveType::ManifestSrc: |
1212 return operativeDirective(m_manifestSrc.get()); | 1236 return operativeDirective(m_manifestSrc.get()); |
1213 case ContentSecurityPolicy::DirectiveType::MediaSrc: | 1237 case ContentSecurityPolicy::DirectiveType::MediaSrc: |
1214 return operativeDirective(m_mediaSrc.get()); | 1238 return operativeDirective(m_mediaSrc.get()); |
1215 case ContentSecurityPolicy::DirectiveType::ObjectSrc: | 1239 case ContentSecurityPolicy::DirectiveType::ObjectSrc: |
1216 return operativeDirective(m_objectSrc.get()); | 1240 return operativeDirective(m_objectSrc.get()); |
1217 case ContentSecurityPolicy::DirectiveType::ScriptSrc: | 1241 case ContentSecurityPolicy::DirectiveType::ScriptSrc: |
1218 return operativeDirective(m_scriptSrc.get()); | 1242 return operativeDirective(m_scriptSrc.get()); |
1219 case ContentSecurityPolicy::DirectiveType::StyleSrc: | 1243 case ContentSecurityPolicy::DirectiveType::StyleSrc: |
1220 return operativeDirective(m_styleSrc.get()); | 1244 return operativeDirective(m_styleSrc.get()); |
1221 // Directives that default to child-src, which defaults to default-src. | 1245 // Directives that default to 'child-src' (which defaults to 'default-src') |
1222 case ContentSecurityPolicy::DirectiveType::FrameSrc: | 1246 case ContentSecurityPolicy::DirectiveType::FrameSrc: |
1223 return operativeDirective(m_frameSrc.get(), | 1247 return operativeDirective(m_frameSrc.get(), |
1224 operativeDirective(m_childSrc.get())); | 1248 operativeDirective(m_childSrc.get())); |
1225 // TODO(mkwst): Reevaluate this. | 1249 // Directives that default to 'script-src' (which defaults to 'default-src') |
1226 case ContentSecurityPolicy::DirectiveType::WorkerSrc: | 1250 case ContentSecurityPolicy::DirectiveType::WorkerSrc: |
1227 return operativeDirective(m_workerSrc.get(), | 1251 return operativeDirective(m_workerSrc.get(), |
1228 operativeDirective(m_childSrc.get())); | 1252 operativeDirective(m_scriptSrc.get())); |
1229 default: | 1253 default: |
1230 return nullptr; | 1254 return nullptr; |
1231 } | 1255 } |
1232 } | 1256 } |
1233 | 1257 |
1234 SourceListDirectiveVector CSPDirectiveList::getSourceVector( | 1258 SourceListDirectiveVector CSPDirectiveList::getSourceVector( |
1235 const ContentSecurityPolicy::DirectiveType& type, | 1259 const ContentSecurityPolicy::DirectiveType& type, |
1236 const CSPDirectiveListVector& policies) { | 1260 const CSPDirectiveListVector& policies) { |
1237 SourceListDirectiveVector sourceListDirectives; | 1261 SourceListDirectiveVector sourceListDirectives; |
1238 for (const auto& policy : policies) { | 1262 for (const auto& policy : policies) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1331 visitor->trace(m_imgSrc); | 1355 visitor->trace(m_imgSrc); |
1332 visitor->trace(m_mediaSrc); | 1356 visitor->trace(m_mediaSrc); |
1333 visitor->trace(m_manifestSrc); | 1357 visitor->trace(m_manifestSrc); |
1334 visitor->trace(m_objectSrc); | 1358 visitor->trace(m_objectSrc); |
1335 visitor->trace(m_scriptSrc); | 1359 visitor->trace(m_scriptSrc); |
1336 visitor->trace(m_styleSrc); | 1360 visitor->trace(m_styleSrc); |
1337 visitor->trace(m_workerSrc); | 1361 visitor->trace(m_workerSrc); |
1338 } | 1362 } |
1339 | 1363 |
1340 } // namespace blink | 1364 } // namespace blink |
OLD | NEW |