| 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 |
| 11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
| 12 * | 12 * |
| 13 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY | 13 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY |
| 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "core/frame/csp/ContentSecurityPolicy.h" | 26 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 27 | 27 |
| 28 #include <memory> | 28 #include <memory> |
| 29 #include "bindings/core/v8/ScriptController.h" | 29 #include "bindings/core/v8/ScriptController.h" |
| 30 #include "bindings/core/v8/SourceLocation.h" | |
| 31 #include "core/dom/DOMStringList.h" | 30 #include "core/dom/DOMStringList.h" |
| 32 #include "core/dom/Document.h" | 31 #include "core/dom/Document.h" |
| 33 #include "core/dom/Element.h" | 32 #include "core/dom/Element.h" |
| 34 #include "core/dom/SandboxFlags.h" | 33 #include "core/dom/SandboxFlags.h" |
| 35 #include "core/dom/TaskRunnerHelper.h" | 34 #include "core/dom/TaskRunnerHelper.h" |
| 36 #include "core/events/EventQueue.h" | 35 #include "core/events/EventQueue.h" |
| 37 #include "core/events/SecurityPolicyViolationEvent.h" | 36 #include "core/events/SecurityPolicyViolationEvent.h" |
| 38 #include "core/frame/FrameClient.h" | 37 #include "core/frame/FrameClient.h" |
| 39 #include "core/frame/LocalDOMWindow.h" | 38 #include "core/frame/LocalDOMWindow.h" |
| 40 #include "core/frame/LocalFrame.h" | 39 #include "core/frame/LocalFrame.h" |
| (...skipping 992 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1033 static void gatherSecurityPolicyViolationEventData( | 1032 static void gatherSecurityPolicyViolationEventData( |
| 1034 SecurityPolicyViolationEventInit& init, | 1033 SecurityPolicyViolationEventInit& init, |
| 1035 ExecutionContext* context, | 1034 ExecutionContext* context, |
| 1036 const String& directiveText, | 1035 const String& directiveText, |
| 1037 const ContentSecurityPolicy::DirectiveType& effectiveType, | 1036 const ContentSecurityPolicy::DirectiveType& effectiveType, |
| 1038 const KURL& blockedURL, | 1037 const KURL& blockedURL, |
| 1039 const String& header, | 1038 const String& header, |
| 1040 RedirectStatus redirectStatus, | 1039 RedirectStatus redirectStatus, |
| 1041 ContentSecurityPolicyHeaderType headerType, | 1040 ContentSecurityPolicyHeaderType headerType, |
| 1042 ContentSecurityPolicy::ViolationType violationType, | 1041 ContentSecurityPolicy::ViolationType violationType, |
| 1043 int contextLine, | 1042 std::unique_ptr<SourceLocation> sourceLocation, |
| 1044 const String& scriptSource) { | 1043 const String& scriptSource) { |
| 1045 if (effectiveType == ContentSecurityPolicy::DirectiveType::FrameAncestors) { | 1044 if (effectiveType == ContentSecurityPolicy::DirectiveType::FrameAncestors) { |
| 1046 // If this load was blocked via 'frame-ancestors', then the URL of | 1045 // If this load was blocked via 'frame-ancestors', then the URL of |
| 1047 // |document| has not yet been initialized. In this case, we'll set both | 1046 // |document| has not yet been initialized. In this case, we'll set both |
| 1048 // 'documentURI' and 'blockedURI' to the blocked document's URL. | 1047 // 'documentURI' and 'blockedURI' to the blocked document's URL. |
| 1049 String strippedURL = stripURLForUseInReport( | 1048 String strippedURL = stripURLForUseInReport( |
| 1050 context, blockedURL, RedirectStatus::NoRedirect, | 1049 context, blockedURL, RedirectStatus::NoRedirect, |
| 1051 ContentSecurityPolicy::DirectiveType::DefaultSrc); | 1050 ContentSecurityPolicy::DirectiveType::DefaultSrc); |
| 1052 init.setDocumentURI(strippedURL); | 1051 init.setDocumentURI(strippedURL); |
| 1053 init.setBlockedURI(strippedURL); | 1052 init.setBlockedURI(strippedURL); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1071 } | 1070 } |
| 1072 | 1071 |
| 1073 String effectiveDirective = | 1072 String effectiveDirective = |
| 1074 ContentSecurityPolicy::getDirectiveName(effectiveType); | 1073 ContentSecurityPolicy::getDirectiveName(effectiveType); |
| 1075 init.setViolatedDirective(effectiveDirective); | 1074 init.setViolatedDirective(effectiveDirective); |
| 1076 init.setEffectiveDirective(effectiveDirective); | 1075 init.setEffectiveDirective(effectiveDirective); |
| 1077 init.setOriginalPolicy(header); | 1076 init.setOriginalPolicy(header); |
| 1078 init.setDisposition(headerType == ContentSecurityPolicyHeaderTypeEnforce | 1077 init.setDisposition(headerType == ContentSecurityPolicyHeaderTypeEnforce |
| 1079 ? "enforce" | 1078 ? "enforce" |
| 1080 : "report"); | 1079 : "report"); |
| 1081 init.setSourceFile(String()); | |
| 1082 init.setLineNumber(contextLine); | |
| 1083 init.setColumnNumber(0); | |
| 1084 init.setStatusCode(0); | 1080 init.setStatusCode(0); |
| 1085 | 1081 |
| 1086 // TODO(mkwst): We only have referrer and status code information for | 1082 // TODO(mkwst): We only have referrer and status code information for |
| 1087 // Documents. It would be nice to get them for Workers as well. | 1083 // Documents. It would be nice to get them for Workers as well. |
| 1088 if (context->isDocument()) { | 1084 if (context->isDocument()) { |
| 1089 Document* document = toDocument(context); | 1085 Document* document = toDocument(context); |
| 1090 DCHECK(document); | 1086 DCHECK(document); |
| 1091 init.setReferrer(document->referrer()); | 1087 init.setReferrer(document->referrer()); |
| 1092 if (!SecurityOrigin::isSecure(context->url()) && document->loader()) | 1088 if (!SecurityOrigin::isSecure(context->url()) && document->loader()) |
| 1093 init.setStatusCode(document->loader()->response().httpStatusCode()); | 1089 init.setStatusCode(document->loader()->response().httpStatusCode()); |
| 1094 } | 1090 } |
| 1095 | 1091 |
| 1096 std::unique_ptr<SourceLocation> location = SourceLocation::capture(context); | 1092 // If no source location is provided, use the source location of the context. |
| 1097 if (location->lineNumber()) { | 1093 if (!sourceLocation) |
| 1098 KURL source = KURL(ParsedURLString, location->url()); | 1094 sourceLocation = SourceLocation::capture(context); |
| 1095 if (sourceLocation->lineNumber()) { |
| 1096 KURL source = KURL(ParsedURLString, sourceLocation->url()); |
| 1099 init.setSourceFile( | 1097 init.setSourceFile( |
| 1100 stripURLForUseInReport(context, source, redirectStatus, effectiveType)); | 1098 stripURLForUseInReport(context, source, redirectStatus, effectiveType)); |
| 1101 init.setLineNumber(location->lineNumber()); | 1099 init.setLineNumber(sourceLocation->lineNumber()); |
| 1102 init.setColumnNumber(location->columnNumber()); | 1100 init.setColumnNumber(sourceLocation->columnNumber()); |
| 1101 } else { |
| 1102 init.setSourceFile(String()); |
| 1103 init.setLineNumber(0); |
| 1104 init.setColumnNumber(0); |
| 1103 } | 1105 } |
| 1104 | 1106 |
| 1105 if (!scriptSource.isEmpty()) | 1107 if (!scriptSource.isEmpty()) |
| 1106 init.setSample(scriptSource.stripWhiteSpace().left(40)); | 1108 init.setSample(scriptSource.stripWhiteSpace().left(40)); |
| 1107 } | 1109 } |
| 1108 | 1110 |
| 1109 void ContentSecurityPolicy::reportViolation( | 1111 void ContentSecurityPolicy::reportViolation( |
| 1110 const String& directiveText, | 1112 const String& directiveText, |
| 1111 const DirectiveType& effectiveType, | 1113 const DirectiveType& effectiveType, |
| 1112 const String& consoleMessage, | 1114 const String& consoleMessage, |
| 1113 const KURL& blockedURL, | 1115 const KURL& blockedURL, |
| 1114 const Vector<String>& reportEndpoints, | 1116 const Vector<String>& reportEndpoints, |
| 1115 const String& header, | 1117 const String& header, |
| 1116 ContentSecurityPolicyHeaderType headerType, | 1118 ContentSecurityPolicyHeaderType headerType, |
| 1117 ViolationType violationType, | 1119 ViolationType violationType, |
| 1120 std::unique_ptr<SourceLocation> sourceLocation, |
| 1118 LocalFrame* contextFrame, | 1121 LocalFrame* contextFrame, |
| 1119 RedirectStatus redirectStatus, | 1122 RedirectStatus redirectStatus, |
| 1120 int contextLine, | |
| 1121 Element* element, | 1123 Element* element, |
| 1122 const String& source) { | 1124 const String& source) { |
| 1123 ASSERT(violationType == URLViolation || blockedURL.isEmpty()); | 1125 ASSERT(violationType == URLViolation || blockedURL.isEmpty()); |
| 1124 | 1126 |
| 1125 // TODO(lukasza): Support sending reports from OOPIFs - | 1127 // TODO(lukasza): Support sending reports from OOPIFs - |
| 1126 // https://crbug.com/611232 (or move CSP child-src and frame-src checks to the | 1128 // https://crbug.com/611232 (or move CSP child-src and frame-src checks to the |
| 1127 // browser process - see https://crbug.com/376522). | 1129 // browser process - see https://crbug.com/376522). |
| 1128 if (!m_executionContext && !contextFrame) { | 1130 if (!m_executionContext && !contextFrame) { |
| 1129 DCHECK(effectiveType == DirectiveType::ChildSrc || | 1131 DCHECK(effectiveType == DirectiveType::ChildSrc || |
| 1130 effectiveType == DirectiveType::FrameSrc || | 1132 effectiveType == DirectiveType::FrameSrc || |
| 1131 effectiveType == DirectiveType::PluginTypes); | 1133 effectiveType == DirectiveType::PluginTypes); |
| 1132 return; | 1134 return; |
| 1133 } | 1135 } |
| 1134 | 1136 |
| 1135 DCHECK((m_executionContext && !contextFrame) || | 1137 DCHECK((m_executionContext && !contextFrame) || |
| 1136 ((effectiveType == DirectiveType::FrameAncestors) && contextFrame)); | 1138 ((effectiveType == DirectiveType::FrameAncestors) && contextFrame)); |
| 1137 | 1139 |
| 1138 SecurityPolicyViolationEventInit violationData; | 1140 SecurityPolicyViolationEventInit violationData; |
| 1139 | 1141 |
| 1140 // If we're processing 'frame-ancestors', use |contextFrame|'s execution | 1142 // If we're processing 'frame-ancestors', use |contextFrame|'s execution |
| 1141 // context to gather data. Otherwise, use the policy's execution context. | 1143 // context to gather data. Otherwise, use the policy's execution context. |
| 1142 ExecutionContext* relevantContext = | 1144 ExecutionContext* relevantContext = |
| 1143 contextFrame ? contextFrame->document() : m_executionContext; | 1145 contextFrame ? contextFrame->document() : m_executionContext; |
| 1144 DCHECK(relevantContext); | 1146 DCHECK(relevantContext); |
| 1145 gatherSecurityPolicyViolationEventData( | 1147 gatherSecurityPolicyViolationEventData( |
| 1146 violationData, relevantContext, directiveText, effectiveType, blockedURL, | 1148 violationData, relevantContext, directiveText, effectiveType, blockedURL, |
| 1147 header, redirectStatus, headerType, violationType, contextLine, source); | 1149 header, redirectStatus, headerType, violationType, |
| 1150 std::move(sourceLocation), source); |
| 1148 | 1151 |
| 1149 // TODO(mkwst): Obviously, we shouldn't hit this check, as extension-loaded | 1152 // TODO(mkwst): Obviously, we shouldn't hit this check, as extension-loaded |
| 1150 // resources should be allowed regardless. We apparently do, however, so | 1153 // resources should be allowed regardless. We apparently do, however, so |
| 1151 // we should at least stop spamming reporting endpoints. See | 1154 // we should at least stop spamming reporting endpoints. See |
| 1152 // https://crbug.com/524356 for detail. | 1155 // https://crbug.com/524356 for detail. |
| 1153 if (!violationData.sourceFile().isEmpty() && | 1156 if (!violationData.sourceFile().isEmpty() && |
| 1154 shouldBypassContentSecurityPolicy( | 1157 shouldBypassContentSecurityPolicy( |
| 1155 KURL(ParsedURLString, violationData.sourceFile()))) { | 1158 KURL(ParsedURLString, violationData.sourceFile()))) { |
| 1156 return; | 1159 return; |
| 1157 } | 1160 } |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1643 if (SecurityOrigin::shouldUseInnerURL(url)) { | 1646 if (SecurityOrigin::shouldUseInnerURL(url)) { |
| 1644 return SchemeRegistry::schemeShouldBypassContentSecurityPolicy( | 1647 return SchemeRegistry::schemeShouldBypassContentSecurityPolicy( |
| 1645 SecurityOrigin::extractInnerURL(url).protocol(), area); | 1648 SecurityOrigin::extractInnerURL(url).protocol(), area); |
| 1646 } else { | 1649 } else { |
| 1647 return SchemeRegistry::schemeShouldBypassContentSecurityPolicy( | 1650 return SchemeRegistry::schemeShouldBypassContentSecurityPolicy( |
| 1648 url.protocol(), area); | 1651 url.protocol(), area); |
| 1649 } | 1652 } |
| 1650 } | 1653 } |
| 1651 | 1654 |
| 1652 } // namespace blink | 1655 } // namespace blink |
| OLD | NEW |