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 |