| 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 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1048 } | 1048 } |
| 1049 | 1049 |
| 1050 static void gatherSecurityPolicyViolationEventData( | 1050 static void gatherSecurityPolicyViolationEventData( |
| 1051 SecurityPolicyViolationEventInit& init, | 1051 SecurityPolicyViolationEventInit& init, |
| 1052 Document* document, | 1052 Document* document, |
| 1053 const String& directiveText, | 1053 const String& directiveText, |
| 1054 const String& effectiveDirective, | 1054 const String& effectiveDirective, |
| 1055 const KURL& blockedURL, | 1055 const KURL& blockedURL, |
| 1056 const String& header, | 1056 const String& header, |
| 1057 RedirectStatus redirectStatus, | 1057 RedirectStatus redirectStatus, |
| 1058 ContentSecurityPolicyHeaderType headerType, |
| 1058 ContentSecurityPolicy::ViolationType violationType, | 1059 ContentSecurityPolicy::ViolationType violationType, |
| 1059 int contextLine) { | 1060 int contextLine) { |
| 1060 if (equalIgnoringCase(effectiveDirective, | 1061 if (equalIgnoringCase(effectiveDirective, |
| 1061 ContentSecurityPolicy::FrameAncestors)) { | 1062 ContentSecurityPolicy::FrameAncestors)) { |
| 1062 // If this load was blocked via 'frame-ancestors', then the URL of | 1063 // If this load was blocked via 'frame-ancestors', then the URL of |
| 1063 // |document| has not yet been initialized. In this case, we'll set both | 1064 // |document| has not yet been initialized. In this case, we'll set both |
| 1064 // 'documentURI' and 'blockedURI' to the blocked document's URL. | 1065 // 'documentURI' and 'blockedURI' to the blocked document's URL. |
| 1065 init.setDocumentURI(blockedURL.getString()); | 1066 init.setDocumentURI(blockedURL.getString()); |
| 1066 init.setBlockedURI(blockedURL.getString()); | 1067 init.setBlockedURI(blockedURL.getString()); |
| 1067 } else { | 1068 } else { |
| 1068 init.setDocumentURI(document->url().getString()); | 1069 init.setDocumentURI(document->url().getString()); |
| 1069 switch (violationType) { | 1070 switch (violationType) { |
| 1070 case ContentSecurityPolicy::InlineViolation: | 1071 case ContentSecurityPolicy::InlineViolation: |
| 1071 init.setBlockedURI("inline"); | 1072 init.setBlockedURI("inline"); |
| 1072 break; | 1073 break; |
| 1073 case ContentSecurityPolicy::EvalViolation: | 1074 case ContentSecurityPolicy::EvalViolation: |
| 1074 init.setBlockedURI("eval"); | 1075 init.setBlockedURI("eval"); |
| 1075 break; | 1076 break; |
| 1076 case ContentSecurityPolicy::URLViolation: | 1077 case ContentSecurityPolicy::URLViolation: |
| 1077 init.setBlockedURI(stripURLForUseInReport( | 1078 init.setBlockedURI(stripURLForUseInReport( |
| 1078 document, blockedURL, redirectStatus, effectiveDirective)); | 1079 document, blockedURL, redirectStatus, effectiveDirective)); |
| 1079 break; | 1080 break; |
| 1080 } | 1081 } |
| 1081 } | 1082 } |
| 1082 init.setReferrer(document->referrer()); | 1083 init.setReferrer(document->referrer()); |
| 1083 init.setViolatedDirective(directiveText); | 1084 init.setViolatedDirective(directiveText); |
| 1084 init.setEffectiveDirective(effectiveDirective); | 1085 init.setEffectiveDirective(effectiveDirective); |
| 1085 init.setOriginalPolicy(header); | 1086 init.setOriginalPolicy(header); |
| 1087 init.setDisposition(headerType == ContentSecurityPolicyHeaderTypeEnforce |
| 1088 ? "enforce" |
| 1089 : "report"); |
| 1086 init.setSourceFile(String()); | 1090 init.setSourceFile(String()); |
| 1087 init.setLineNumber(contextLine); | 1091 init.setLineNumber(contextLine); |
| 1088 init.setColumnNumber(0); | 1092 init.setColumnNumber(0); |
| 1089 init.setStatusCode(0); | 1093 init.setStatusCode(0); |
| 1090 | 1094 |
| 1091 if (!SecurityOrigin::isSecure(document->url()) && document->loader()) | 1095 if (!SecurityOrigin::isSecure(document->url()) && document->loader()) |
| 1092 init.setStatusCode(document->loader()->response().httpStatusCode()); | 1096 init.setStatusCode(document->loader()->response().httpStatusCode()); |
| 1093 | 1097 |
| 1094 std::unique_ptr<SourceLocation> location = SourceLocation::capture(document); | 1098 std::unique_ptr<SourceLocation> location = SourceLocation::capture(document); |
| 1095 if (location->lineNumber()) { | 1099 if (location->lineNumber()) { |
| 1096 KURL source = KURL(ParsedURLString, location->url()); | 1100 KURL source = KURL(ParsedURLString, location->url()); |
| 1097 init.setSourceFile(stripURLForUseInReport(document, source, redirectStatus, | 1101 init.setSourceFile(stripURLForUseInReport(document, source, redirectStatus, |
| 1098 effectiveDirective)); | 1102 effectiveDirective)); |
| 1099 init.setLineNumber(location->lineNumber()); | 1103 init.setLineNumber(location->lineNumber()); |
| 1100 init.setColumnNumber(location->columnNumber()); | 1104 init.setColumnNumber(location->columnNumber()); |
| 1101 } | 1105 } |
| 1102 } | 1106 } |
| 1103 | 1107 |
| 1104 void ContentSecurityPolicy::reportViolation( | 1108 void ContentSecurityPolicy::reportViolation( |
| 1105 const String& directiveText, | 1109 const String& directiveText, |
| 1106 const String& effectiveDirective, | 1110 const String& effectiveDirective, |
| 1107 const String& consoleMessage, | 1111 const String& consoleMessage, |
| 1108 const KURL& blockedURL, | 1112 const KURL& blockedURL, |
| 1109 const Vector<String>& reportEndpoints, | 1113 const Vector<String>& reportEndpoints, |
| 1110 const String& header, | 1114 const String& header, |
| 1115 ContentSecurityPolicyHeaderType headerType, |
| 1111 ViolationType violationType, | 1116 ViolationType violationType, |
| 1112 LocalFrame* contextFrame, | 1117 LocalFrame* contextFrame, |
| 1113 RedirectStatus redirectStatus, | 1118 RedirectStatus redirectStatus, |
| 1114 int contextLine) { | 1119 int contextLine) { |
| 1115 ASSERT(violationType == URLViolation || blockedURL.isEmpty()); | 1120 ASSERT(violationType == URLViolation || blockedURL.isEmpty()); |
| 1116 | 1121 |
| 1117 // TODO(lukasza): Support sending reports from OOPIFs - | 1122 // TODO(lukasza): Support sending reports from OOPIFs - |
| 1118 // https://crbug.com/611232 (or move CSP child-src and frame-src checks to the | 1123 // https://crbug.com/611232 (or move CSP child-src and frame-src checks to the |
| 1119 // browser process - see https://crbug.com/376522). | 1124 // browser process - see https://crbug.com/376522). |
| 1120 if (!m_executionContext && !contextFrame) { | 1125 if (!m_executionContext && !contextFrame) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1134 | 1139 |
| 1135 // FIXME: Support sending reports from worker. | 1140 // FIXME: Support sending reports from worker. |
| 1136 Document* document = | 1141 Document* document = |
| 1137 contextFrame ? contextFrame->document() : this->document(); | 1142 contextFrame ? contextFrame->document() : this->document(); |
| 1138 if (!document) | 1143 if (!document) |
| 1139 return; | 1144 return; |
| 1140 | 1145 |
| 1141 SecurityPolicyViolationEventInit violationData; | 1146 SecurityPolicyViolationEventInit violationData; |
| 1142 gatherSecurityPolicyViolationEventData( | 1147 gatherSecurityPolicyViolationEventData( |
| 1143 violationData, document, directiveText, effectiveDirective, blockedURL, | 1148 violationData, document, directiveText, effectiveDirective, blockedURL, |
| 1144 header, redirectStatus, violationType, contextLine); | 1149 header, redirectStatus, headerType, violationType, contextLine); |
| 1145 | 1150 |
| 1146 // TODO(mkwst): Obviously, we shouldn't hit this check, as extension-loaded | 1151 // TODO(mkwst): Obviously, we shouldn't hit this check, as extension-loaded |
| 1147 // resources should be allowed regardless. We apparently do, however, so | 1152 // resources should be allowed regardless. We apparently do, however, so |
| 1148 // we should at least stop spamming reporting endpoints. See | 1153 // we should at least stop spamming reporting endpoints. See |
| 1149 // https://crbug.com/524356 for detail. | 1154 // https://crbug.com/524356 for detail. |
| 1150 if (!violationData.sourceFile().isEmpty() && | 1155 if (!violationData.sourceFile().isEmpty() && |
| 1151 SchemeRegistry::schemeShouldBypassContentSecurityPolicy( | 1156 SchemeRegistry::schemeShouldBypassContentSecurityPolicy( |
| 1152 KURL(ParsedURLString, violationData.sourceFile()).protocol())) | 1157 KURL(ParsedURLString, violationData.sourceFile()).protocol())) |
| 1153 return; | 1158 return; |
| 1154 | 1159 |
| 1155 // We need to be careful here when deciding what information to send to the | 1160 // We need to be careful here when deciding what information to send to the |
| 1156 // report-uri. Currently, we send only the current document's URL and the | 1161 // report-uri. Currently, we send only the current document's URL and the |
| 1157 // directive that was violated. The document's URL is safe to send because | 1162 // directive that was violated. The document's URL is safe to send because |
| 1158 // it's the document itself that's requesting that it be sent. You could | 1163 // it's the document itself that's requesting that it be sent. You could |
| 1159 // make an argument that we shouldn't send HTTPS document URLs to HTTP | 1164 // make an argument that we shouldn't send HTTPS document URLs to HTTP |
| 1160 // report-uris (for the same reasons that we supress the Referer in that | 1165 // report-uris (for the same reasons that we supress the Referer in that |
| 1161 // case), but the Referer is sent implicitly whereas this request is only | 1166 // case), but the Referer is sent implicitly whereas this request is only |
| 1162 // sent explicitly. As for which directive was violated, that's pretty | 1167 // sent explicitly. As for which directive was violated, that's pretty |
| 1163 // harmless information. | 1168 // harmless information. |
| 1164 | 1169 |
| 1165 std::unique_ptr<JSONObject> cspReport = JSONObject::create(); | 1170 std::unique_ptr<JSONObject> cspReport = JSONObject::create(); |
| 1166 cspReport->setString("document-uri", violationData.documentURI()); | 1171 cspReport->setString("document-uri", violationData.documentURI()); |
| 1167 cspReport->setString("referrer", violationData.referrer()); | 1172 cspReport->setString("referrer", violationData.referrer()); |
| 1168 cspReport->setString("violated-directive", violationData.violatedDirective()); | 1173 cspReport->setString("violated-directive", violationData.violatedDirective()); |
| 1169 cspReport->setString("effective-directive", | 1174 cspReport->setString("effective-directive", |
| 1170 violationData.effectiveDirective()); | 1175 violationData.effectiveDirective()); |
| 1171 cspReport->setString("original-policy", violationData.originalPolicy()); | 1176 cspReport->setString("original-policy", violationData.originalPolicy()); |
| 1177 cspReport->setString("disposition", violationData.disposition()); |
| 1172 cspReport->setString("blocked-uri", violationData.blockedURI()); | 1178 cspReport->setString("blocked-uri", violationData.blockedURI()); |
| 1173 if (violationData.lineNumber()) | 1179 if (violationData.lineNumber()) |
| 1174 cspReport->setInteger("line-number", violationData.lineNumber()); | 1180 cspReport->setInteger("line-number", violationData.lineNumber()); |
| 1175 if (violationData.columnNumber()) | 1181 if (violationData.columnNumber()) |
| 1176 cspReport->setInteger("column-number", violationData.columnNumber()); | 1182 cspReport->setInteger("column-number", violationData.columnNumber()); |
| 1177 if (!violationData.sourceFile().isEmpty()) | 1183 if (!violationData.sourceFile().isEmpty()) |
| 1178 cspReport->setString("source-file", violationData.sourceFile()); | 1184 cspReport->setString("source-file", violationData.sourceFile()); |
| 1179 cspReport->setInteger("status-code", violationData.statusCode()); | 1185 cspReport->setInteger("status-code", violationData.statusCode()); |
| 1180 | 1186 |
| 1181 std::unique_ptr<JSONObject> reportObject = JSONObject::create(); | 1187 std::unique_ptr<JSONObject> reportObject = JSONObject::create(); |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1479 // Collisions have no security impact, so we can save space by storing only | 1485 // Collisions have no security impact, so we can save space by storing only |
| 1480 // the string's hash rather than the whole report. | 1486 // the string's hash rather than the whole report. |
| 1481 return !m_violationReportsSent.contains(report.impl()->hash()); | 1487 return !m_violationReportsSent.contains(report.impl()->hash()); |
| 1482 } | 1488 } |
| 1483 | 1489 |
| 1484 void ContentSecurityPolicy::didSendViolationReport(const String& report) { | 1490 void ContentSecurityPolicy::didSendViolationReport(const String& report) { |
| 1485 m_violationReportsSent.add(report.impl()->hash()); | 1491 m_violationReportsSent.add(report.impl()->hash()); |
| 1486 } | 1492 } |
| 1487 | 1493 |
| 1488 } // namespace blink | 1494 } // namespace blink |
| OLD | NEW |