| 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 #include "wtf/NotFound.h" | 66 #include "wtf/NotFound.h" |
| 67 #include "wtf/PtrUtil.h" | 67 #include "wtf/PtrUtil.h" |
| 68 #include "wtf/StringHasher.h" | 68 #include "wtf/StringHasher.h" |
| 69 #include "wtf/text/ParsingUtilities.h" | 69 #include "wtf/text/ParsingUtilities.h" |
| 70 #include "wtf/text/StringBuilder.h" | 70 #include "wtf/text/StringBuilder.h" |
| 71 #include "wtf/text/StringUTF8Adaptor.h" | 71 #include "wtf/text/StringUTF8Adaptor.h" |
| 72 #include <memory> | 72 #include <memory> |
| 73 | 73 |
| 74 namespace blink { | 74 namespace blink { |
| 75 | 75 |
| 76 // CSP Level 1 Directives |
| 77 const char ContentSecurityPolicy::ConnectSrc[] = "connect-src"; |
| 78 const char ContentSecurityPolicy::DefaultSrc[] = "default-src"; |
| 79 const char ContentSecurityPolicy::FontSrc[] = "font-src"; |
| 80 const char ContentSecurityPolicy::FrameSrc[] = "frame-src"; |
| 81 const char ContentSecurityPolicy::ImgSrc[] = "img-src"; |
| 82 const char ContentSecurityPolicy::MediaSrc[] = "media-src"; |
| 83 const char ContentSecurityPolicy::ObjectSrc[] = "object-src"; |
| 84 const char ContentSecurityPolicy::ReportURI[] = "report-uri"; |
| 85 const char ContentSecurityPolicy::Sandbox[] = "sandbox"; |
| 86 const char ContentSecurityPolicy::ScriptSrc[] = "script-src"; |
| 87 const char ContentSecurityPolicy::StyleSrc[] = "style-src"; |
| 88 |
| 89 // CSP Level 2 Directives |
| 90 const char ContentSecurityPolicy::BaseURI[] = "base-uri"; |
| 91 const char ContentSecurityPolicy::ChildSrc[] = "child-src"; |
| 92 const char ContentSecurityPolicy::FormAction[] = "form-action"; |
| 93 const char ContentSecurityPolicy::FrameAncestors[] = "frame-ancestors"; |
| 94 const char ContentSecurityPolicy::PluginTypes[] = "plugin-types"; |
| 95 |
| 96 // CSP Level 3 Directives |
| 97 const char ContentSecurityPolicy::ManifestSrc[] = "manifest-src"; |
| 98 const char ContentSecurityPolicy::WorkerSrc[] = "worker-src"; |
| 99 |
| 100 // Mixed Content Directive |
| 101 // https://w3c.github.io/webappsec/specs/mixedcontent/#strict-mode |
| 102 const char ContentSecurityPolicy::BlockAllMixedContent[] = |
| 103 "block-all-mixed-content"; |
| 104 |
| 105 // https://w3c.github.io/webappsec/specs/upgrade/ |
| 106 const char ContentSecurityPolicy::UpgradeInsecureRequests[] = |
| 107 "upgrade-insecure-requests"; |
| 108 |
| 109 // https://mikewest.github.io/cors-rfc1918/#csp |
| 110 const char ContentSecurityPolicy::TreatAsPublicAddress[] = |
| 111 "treat-as-public-address"; |
| 112 |
| 113 // https://w3c.github.io/webappsec-subresource-integrity/#require-sri-for |
| 114 const char ContentSecurityPolicy::RequireSRIFor[] = "require-sri-for"; |
| 115 |
| 116 bool ContentSecurityPolicy::isDirectiveName(const String& name) { |
| 117 return ( |
| 118 equalIgnoringCase(name, ConnectSrc) || |
| 119 equalIgnoringCase(name, DefaultSrc) || equalIgnoringCase(name, FontSrc) || |
| 120 equalIgnoringCase(name, FrameSrc) || equalIgnoringCase(name, ImgSrc) || |
| 121 equalIgnoringCase(name, MediaSrc) || equalIgnoringCase(name, ObjectSrc) || |
| 122 equalIgnoringCase(name, ReportURI) || equalIgnoringCase(name, Sandbox) || |
| 123 equalIgnoringCase(name, ScriptSrc) || equalIgnoringCase(name, StyleSrc) || |
| 124 equalIgnoringCase(name, BaseURI) || equalIgnoringCase(name, ChildSrc) || |
| 125 equalIgnoringCase(name, FormAction) || |
| 126 equalIgnoringCase(name, FrameAncestors) || |
| 127 equalIgnoringCase(name, PluginTypes) || |
| 128 equalIgnoringCase(name, ManifestSrc) || |
| 129 equalIgnoringCase(name, WorkerSrc) || |
| 130 equalIgnoringCase(name, BlockAllMixedContent) || |
| 131 equalIgnoringCase(name, UpgradeInsecureRequests) || |
| 132 equalIgnoringCase(name, TreatAsPublicAddress) || |
| 133 equalIgnoringCase(name, RequireSRIFor)); |
| 134 } |
| 135 |
| 76 bool ContentSecurityPolicy::isNonceableElement(const Element* element) { | 136 bool ContentSecurityPolicy::isNonceableElement(const Element* element) { |
| 77 if (!element->fastHasAttribute(HTMLNames::nonceAttr)) | 137 if (!element->fastHasAttribute(HTMLNames::nonceAttr)) |
| 78 return false; | 138 return false; |
| 79 | 139 |
| 80 bool nonceable = true; | 140 bool nonceable = true; |
| 81 | 141 |
| 82 // To prevent an attacker from hijacking an existing nonce via a dangling | 142 // To prevent an attacker from hijacking an existing nonce via a dangling |
| 83 // markup injection, we walk through the attributes of each nonced script | 143 // markup injection, we walk through the attributes of each nonced script |
| 84 // element: if their names or values contain "<script" or "<style", we won't | 144 // element: if their names or values contain "<script" or "<style", we won't |
| 85 // apply the nonce when loading script. | 145 // apply the nonce when loading script. |
| (...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 974 } | 1034 } |
| 975 | 1035 |
| 976 void ContentSecurityPolicy::enforceStrictMixedContentChecking() { | 1036 void ContentSecurityPolicy::enforceStrictMixedContentChecking() { |
| 977 m_insecureRequestPolicy |= kBlockAllMixedContent; | 1037 m_insecureRequestPolicy |= kBlockAllMixedContent; |
| 978 } | 1038 } |
| 979 | 1039 |
| 980 void ContentSecurityPolicy::upgradeInsecureRequests() { | 1040 void ContentSecurityPolicy::upgradeInsecureRequests() { |
| 981 m_insecureRequestPolicy |= kUpgradeInsecureRequests; | 1041 m_insecureRequestPolicy |= kUpgradeInsecureRequests; |
| 982 } | 1042 } |
| 983 | 1043 |
| 984 static String stripURLForUseInReport( | 1044 static String stripURLForUseInReport(ExecutionContext* context, |
| 985 ExecutionContext* context, | 1045 const KURL& url, |
| 986 const KURL& url, | 1046 RedirectStatus redirectStatus, |
| 987 RedirectStatus redirectStatus, | 1047 const String& effectiveDirective) { |
| 988 const ContentSecurityPolicy::DirectiveType& effectiveType) { | |
| 989 if (!url.isValid()) | 1048 if (!url.isValid()) |
| 990 return String(); | 1049 return String(); |
| 991 if (!url.isHierarchical() || url.protocolIs("file")) | 1050 if (!url.isHierarchical() || url.protocolIs("file")) |
| 992 return url.protocol(); | 1051 return url.protocol(); |
| 993 | 1052 |
| 994 // Until we're more careful about the way we deal with navigations in frames | 1053 // Until we're more careful about the way we deal with navigations in frames |
| 995 // (and, by extension, in plugin documents), strip cross-origin 'frame-src' | 1054 // (and, by extension, in plugin documents), strip cross-origin 'frame-src' |
| 996 // and 'object-src' violations down to an origin. https://crbug.com/633306 | 1055 // and 'object-src' violations down to an origin. https://crbug.com/633306 |
| 997 bool canSafelyExposeURL = | 1056 bool canSafelyExposeURL = |
| 998 context->getSecurityOrigin()->canRequest(url) || | 1057 context->getSecurityOrigin()->canRequest(url) || |
| 999 (redirectStatus == RedirectStatus::NoRedirect && | 1058 (redirectStatus == RedirectStatus::NoRedirect && |
| 1000 effectiveType != ContentSecurityPolicy::DirectiveType::FrameSrc && | 1059 !equalIgnoringCase(effectiveDirective, |
| 1001 effectiveType != ContentSecurityPolicy::DirectiveType::ObjectSrc); | 1060 ContentSecurityPolicy::FrameSrc) && |
| 1061 !equalIgnoringCase(effectiveDirective, |
| 1062 ContentSecurityPolicy::ObjectSrc)); |
| 1002 | 1063 |
| 1003 if (canSafelyExposeURL) { | 1064 if (canSafelyExposeURL) { |
| 1004 // 'KURL::strippedForUseAsReferrer()' dumps 'String()' for non-webby URLs. | 1065 // 'KURL::strippedForUseAsReferrer()' dumps 'String()' for non-webby URLs. |
| 1005 // It's better for developers if we return the origin of those URLs rather | 1066 // It's better for developers if we return the origin of those URLs rather |
| 1006 // than nothing. | 1067 // than nothing. |
| 1007 if (url.protocolIsInHTTPFamily()) | 1068 if (url.protocolIsInHTTPFamily()) |
| 1008 return url.strippedForUseAsReferrer(); | 1069 return url.strippedForUseAsReferrer(); |
| 1009 } | 1070 } |
| 1010 return SecurityOrigin::create(url)->toString(); | 1071 return SecurityOrigin::create(url)->toString(); |
| 1011 } | 1072 } |
| 1012 | 1073 |
| 1013 static void gatherSecurityPolicyViolationEventData( | 1074 static void gatherSecurityPolicyViolationEventData( |
| 1014 SecurityPolicyViolationEventInit& init, | 1075 SecurityPolicyViolationEventInit& init, |
| 1015 ExecutionContext* context, | 1076 ExecutionContext* context, |
| 1016 const String& directiveText, | 1077 const String& directiveText, |
| 1017 const ContentSecurityPolicy::DirectiveType& effectiveType, | 1078 const String& effectiveDirective, |
| 1018 const KURL& blockedURL, | 1079 const KURL& blockedURL, |
| 1019 const String& header, | 1080 const String& header, |
| 1020 RedirectStatus redirectStatus, | 1081 RedirectStatus redirectStatus, |
| 1021 ContentSecurityPolicyHeaderType headerType, | 1082 ContentSecurityPolicyHeaderType headerType, |
| 1022 ContentSecurityPolicy::ViolationType violationType, | 1083 ContentSecurityPolicy::ViolationType violationType, |
| 1023 int contextLine) { | 1084 int contextLine) { |
| 1024 if (effectiveType == ContentSecurityPolicy::DirectiveType::FrameAncestors) { | 1085 if (equalIgnoringCase(effectiveDirective, |
| 1086 ContentSecurityPolicy::FrameAncestors)) { |
| 1025 // If this load was blocked via 'frame-ancestors', then the URL of | 1087 // If this load was blocked via 'frame-ancestors', then the URL of |
| 1026 // |document| has not yet been initialized. In this case, we'll set both | 1088 // |document| has not yet been initialized. In this case, we'll set both |
| 1027 // 'documentURI' and 'blockedURI' to the blocked document's URL. | 1089 // 'documentURI' and 'blockedURI' to the blocked document's URL. |
| 1028 init.setDocumentURI(blockedURL.getString()); | 1090 init.setDocumentURI(blockedURL.getString()); |
| 1029 init.setBlockedURI(blockedURL.getString()); | 1091 init.setBlockedURI(blockedURL.getString()); |
| 1030 } else { | 1092 } else { |
| 1031 init.setDocumentURI(context->url().getString()); | 1093 init.setDocumentURI(context->url().getString()); |
| 1032 switch (violationType) { | 1094 switch (violationType) { |
| 1033 case ContentSecurityPolicy::InlineViolation: | 1095 case ContentSecurityPolicy::InlineViolation: |
| 1034 init.setBlockedURI("inline"); | 1096 init.setBlockedURI("inline"); |
| 1035 break; | 1097 break; |
| 1036 case ContentSecurityPolicy::EvalViolation: | 1098 case ContentSecurityPolicy::EvalViolation: |
| 1037 init.setBlockedURI("eval"); | 1099 init.setBlockedURI("eval"); |
| 1038 break; | 1100 break; |
| 1039 case ContentSecurityPolicy::URLViolation: | 1101 case ContentSecurityPolicy::URLViolation: |
| 1040 init.setBlockedURI(stripURLForUseInReport( | 1102 init.setBlockedURI(stripURLForUseInReport( |
| 1041 context, blockedURL, redirectStatus, effectiveType)); | 1103 context, blockedURL, redirectStatus, effectiveDirective)); |
| 1042 break; | 1104 break; |
| 1043 } | 1105 } |
| 1044 } | 1106 } |
| 1045 | 1107 |
| 1046 String effectiveDirective = | |
| 1047 ContentSecurityPolicy::getDirectiveName(effectiveType); | |
| 1048 init.setViolatedDirective(effectiveDirective); | 1108 init.setViolatedDirective(effectiveDirective); |
| 1049 init.setEffectiveDirective(effectiveDirective); | 1109 init.setEffectiveDirective(effectiveDirective); |
| 1050 init.setOriginalPolicy(header); | 1110 init.setOriginalPolicy(header); |
| 1051 init.setDisposition(headerType == ContentSecurityPolicyHeaderTypeEnforce | 1111 init.setDisposition(headerType == ContentSecurityPolicyHeaderTypeEnforce |
| 1052 ? "enforce" | 1112 ? "enforce" |
| 1053 : "report"); | 1113 : "report"); |
| 1054 init.setSourceFile(String()); | 1114 init.setSourceFile(String()); |
| 1055 init.setLineNumber(contextLine); | 1115 init.setLineNumber(contextLine); |
| 1056 init.setColumnNumber(0); | 1116 init.setColumnNumber(0); |
| 1057 init.setStatusCode(0); | 1117 init.setStatusCode(0); |
| 1058 | 1118 |
| 1059 // TODO(mkwst): We only have referrer and status code information for | 1119 // TODO(mkwst): We only have referrer and status code information for |
| 1060 // Documents. It would be nice to get them for Workers as well. | 1120 // Documents. It would be nice to get them for Workers as well. |
| 1061 if (context->isDocument()) { | 1121 if (context->isDocument()) { |
| 1062 Document* document = toDocument(context); | 1122 Document* document = toDocument(context); |
| 1063 DCHECK(document); | 1123 DCHECK(document); |
| 1064 init.setReferrer(document->referrer()); | 1124 init.setReferrer(document->referrer()); |
| 1065 if (!SecurityOrigin::isSecure(context->url()) && document->loader()) | 1125 if (!SecurityOrigin::isSecure(context->url()) && document->loader()) |
| 1066 init.setStatusCode(document->loader()->response().httpStatusCode()); | 1126 init.setStatusCode(document->loader()->response().httpStatusCode()); |
| 1067 } | 1127 } |
| 1068 | 1128 |
| 1069 std::unique_ptr<SourceLocation> location = SourceLocation::capture(context); | 1129 std::unique_ptr<SourceLocation> location = SourceLocation::capture(context); |
| 1070 if (location->lineNumber()) { | 1130 if (location->lineNumber()) { |
| 1071 KURL source = KURL(ParsedURLString, location->url()); | 1131 KURL source = KURL(ParsedURLString, location->url()); |
| 1072 init.setSourceFile( | 1132 init.setSourceFile(stripURLForUseInReport(context, source, redirectStatus, |
| 1073 stripURLForUseInReport(context, source, redirectStatus, effectiveType)); | 1133 effectiveDirective)); |
| 1074 init.setLineNumber(location->lineNumber()); | 1134 init.setLineNumber(location->lineNumber()); |
| 1075 init.setColumnNumber(location->columnNumber()); | 1135 init.setColumnNumber(location->columnNumber()); |
| 1076 } | 1136 } |
| 1077 } | 1137 } |
| 1078 | 1138 |
| 1079 void ContentSecurityPolicy::reportViolation( | 1139 void ContentSecurityPolicy::reportViolation( |
| 1080 const String& directiveText, | 1140 const String& directiveText, |
| 1081 const DirectiveType& effectiveType, | 1141 const String& effectiveDirective, |
| 1082 const String& consoleMessage, | 1142 const String& consoleMessage, |
| 1083 const KURL& blockedURL, | 1143 const KURL& blockedURL, |
| 1084 const Vector<String>& reportEndpoints, | 1144 const Vector<String>& reportEndpoints, |
| 1085 const String& header, | 1145 const String& header, |
| 1086 ContentSecurityPolicyHeaderType headerType, | 1146 ContentSecurityPolicyHeaderType headerType, |
| 1087 ViolationType violationType, | 1147 ViolationType violationType, |
| 1088 LocalFrame* contextFrame, | 1148 LocalFrame* contextFrame, |
| 1089 RedirectStatus redirectStatus, | 1149 RedirectStatus redirectStatus, |
| 1090 int contextLine, | 1150 int contextLine, |
| 1091 Element* element) { | 1151 Element* element) { |
| 1092 ASSERT(violationType == URLViolation || blockedURL.isEmpty()); | 1152 ASSERT(violationType == URLViolation || blockedURL.isEmpty()); |
| 1093 | 1153 |
| 1094 // TODO(lukasza): Support sending reports from OOPIFs - | 1154 // TODO(lukasza): Support sending reports from OOPIFs - |
| 1095 // https://crbug.com/611232 (or move CSP child-src and frame-src checks to the | 1155 // https://crbug.com/611232 (or move CSP child-src and frame-src checks to the |
| 1096 // browser process - see https://crbug.com/376522). | 1156 // browser process - see https://crbug.com/376522). |
| 1097 if (!m_executionContext && !contextFrame) { | 1157 if (!m_executionContext && !contextFrame) { |
| 1098 DCHECK(effectiveType == DirectiveType::ChildSrc || | 1158 DCHECK(equalIgnoringCase(effectiveDirective, |
| 1099 effectiveType == DirectiveType::FrameSrc || | 1159 ContentSecurityPolicy::ChildSrc) || |
| 1100 effectiveType == DirectiveType::PluginTypes); | 1160 equalIgnoringCase(effectiveDirective, |
| 1161 ContentSecurityPolicy::FrameSrc) || |
| 1162 equalIgnoringCase(effectiveDirective, |
| 1163 ContentSecurityPolicy::PluginTypes)); |
| 1101 return; | 1164 return; |
| 1102 } | 1165 } |
| 1103 | 1166 |
| 1104 DCHECK((m_executionContext && !contextFrame) || | 1167 DCHECK((m_executionContext && !contextFrame) || |
| 1105 ((effectiveType == DirectiveType::FrameAncestors) && contextFrame)); | 1168 (equalIgnoringCase(effectiveDirective, |
| 1169 ContentSecurityPolicy::FrameAncestors) && |
| 1170 contextFrame)); |
| 1106 | 1171 |
| 1107 SecurityPolicyViolationEventInit violationData; | 1172 SecurityPolicyViolationEventInit violationData; |
| 1108 | 1173 |
| 1109 // If we're processing 'frame-ancestors', use |contextFrame|'s execution | 1174 // If we're processing 'frame-ancestors', use |contextFrame|'s execution |
| 1110 // context to gather data. Otherwise, use the policy's execution context. | 1175 // context to gather data. Otherwise, use the policy's execution context. |
| 1111 ExecutionContext* relevantContext = | 1176 ExecutionContext* relevantContext = |
| 1112 contextFrame ? contextFrame->document() : m_executionContext; | 1177 contextFrame ? contextFrame->document() : m_executionContext; |
| 1113 DCHECK(relevantContext); | 1178 DCHECK(relevantContext); |
| 1114 gatherSecurityPolicyViolationEventData( | 1179 gatherSecurityPolicyViolationEventData( |
| 1115 violationData, relevantContext, directiveText, effectiveType, blockedURL, | 1180 violationData, relevantContext, directiveText, effectiveDirective, |
| 1116 header, redirectStatus, headerType, violationType, contextLine); | 1181 blockedURL, header, redirectStatus, headerType, violationType, |
| 1182 contextLine); |
| 1117 | 1183 |
| 1118 // TODO(mkwst): Obviously, we shouldn't hit this check, as extension-loaded | 1184 // TODO(mkwst): Obviously, we shouldn't hit this check, as extension-loaded |
| 1119 // resources should be allowed regardless. We apparently do, however, so | 1185 // resources should be allowed regardless. We apparently do, however, so |
| 1120 // we should at least stop spamming reporting endpoints. See | 1186 // we should at least stop spamming reporting endpoints. See |
| 1121 // https://crbug.com/524356 for detail. | 1187 // https://crbug.com/524356 for detail. |
| 1122 if (!violationData.sourceFile().isEmpty() && | 1188 if (!violationData.sourceFile().isEmpty() && |
| 1123 SchemeRegistry::schemeShouldBypassContentSecurityPolicy( | 1189 SchemeRegistry::schemeShouldBypassContentSecurityPolicy( |
| 1124 KURL(ParsedURLString, violationData.sourceFile()).protocol())) { | 1190 KURL(ParsedURLString, violationData.sourceFile()).protocol())) { |
| 1125 return; | 1191 return; |
| 1126 } | 1192 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 if (!frame) | 1259 if (!frame) |
| 1194 return; | 1260 return; |
| 1195 | 1261 |
| 1196 for (const String& endpoint : reportEndpoints) { | 1262 for (const String& endpoint : reportEndpoints) { |
| 1197 // If we have a context frame we're dealing with 'frame-ancestors' and we | 1263 // If we have a context frame we're dealing with 'frame-ancestors' and we |
| 1198 // don't have our own execution context. Use the frame's document to | 1264 // don't have our own execution context. Use the frame's document to |
| 1199 // complete the endpoint URL, overriding its URL with the blocked | 1265 // complete the endpoint URL, overriding its URL with the blocked |
| 1200 // document's URL. | 1266 // document's URL. |
| 1201 DCHECK(!contextFrame || !m_executionContext); | 1267 DCHECK(!contextFrame || !m_executionContext); |
| 1202 DCHECK(!contextFrame || | 1268 DCHECK(!contextFrame || |
| 1203 getDirectiveType(violationData.effectiveDirective()) == | 1269 equalIgnoringCase(violationData.effectiveDirective(), |
| 1204 DirectiveType::FrameAncestors); | 1270 FrameAncestors)); |
| 1205 KURL url = | 1271 KURL url = |
| 1206 contextFrame | 1272 contextFrame |
| 1207 ? frame->document()->completeURLWithOverride( | 1273 ? frame->document()->completeURLWithOverride( |
| 1208 endpoint, KURL(ParsedURLString, violationData.blockedURI())) | 1274 endpoint, KURL(ParsedURLString, violationData.blockedURI())) |
| 1209 : completeURL(endpoint); | 1275 : completeURL(endpoint); |
| 1210 PingLoader::sendViolationReport( | 1276 PingLoader::sendViolationReport( |
| 1211 frame, url, report, PingLoader::ContentSecurityPolicyViolationReport); | 1277 frame, url, report, PingLoader::ContentSecurityPolicyViolationReport); |
| 1212 } | 1278 } |
| 1213 } | 1279 } |
| 1214 } | 1280 } |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1296 | 1362 |
| 1297 String message = | 1363 String message = |
| 1298 "Unrecognized Content-Security-Policy directive '" + name + "'.\n"; | 1364 "Unrecognized Content-Security-Policy directive '" + name + "'.\n"; |
| 1299 MessageLevel level = ErrorMessageLevel; | 1365 MessageLevel level = ErrorMessageLevel; |
| 1300 if (equalIgnoringCase(name, allow)) { | 1366 if (equalIgnoringCase(name, allow)) { |
| 1301 message = allowMessage; | 1367 message = allowMessage; |
| 1302 } else if (equalIgnoringCase(name, options)) { | 1368 } else if (equalIgnoringCase(name, options)) { |
| 1303 message = optionsMessage; | 1369 message = optionsMessage; |
| 1304 } else if (equalIgnoringCase(name, policyURI)) { | 1370 } else if (equalIgnoringCase(name, policyURI)) { |
| 1305 message = policyURIMessage; | 1371 message = policyURIMessage; |
| 1306 } else if (getDirectiveType(name) != DirectiveType::Undefined) { | 1372 } else if (isDirectiveName(name)) { |
| 1307 message = "The Content-Security-Policy directive '" + name + | 1373 message = "The Content-Security-Policy directive '" + name + |
| 1308 "' is implemented behind a flag which is currently disabled.\n"; | 1374 "' is implemented behind a flag which is currently disabled.\n"; |
| 1309 level = InfoMessageLevel; | 1375 level = InfoMessageLevel; |
| 1310 } | 1376 } |
| 1311 | 1377 |
| 1312 logToConsole(message, level); | 1378 logToConsole(message, level); |
| 1313 } | 1379 } |
| 1314 | 1380 |
| 1315 void ContentSecurityPolicy::reportDirectiveAsSourceExpression( | 1381 void ContentSecurityPolicy::reportDirectiveAsSourceExpression( |
| 1316 const String& directiveName, | 1382 const String& directiveName, |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1483 const String& report) const { | 1549 const String& report) const { |
| 1484 // Collisions have no security impact, so we can save space by storing only | 1550 // Collisions have no security impact, so we can save space by storing only |
| 1485 // the string's hash rather than the whole report. | 1551 // the string's hash rather than the whole report. |
| 1486 return !m_violationReportsSent.contains(report.impl()->hash()); | 1552 return !m_violationReportsSent.contains(report.impl()->hash()); |
| 1487 } | 1553 } |
| 1488 | 1554 |
| 1489 void ContentSecurityPolicy::didSendViolationReport(const String& report) { | 1555 void ContentSecurityPolicy::didSendViolationReport(const String& report) { |
| 1490 m_violationReportsSent.add(report.impl()->hash()); | 1556 m_violationReportsSent.add(report.impl()->hash()); |
| 1491 } | 1557 } |
| 1492 | 1558 |
| 1493 const char* ContentSecurityPolicy::getDirectiveName(const DirectiveType& type) { | |
| 1494 switch (type) { | |
| 1495 case DirectiveType::BaseURI: | |
| 1496 return "base-uri"; | |
| 1497 case DirectiveType::BlockAllMixedContent: | |
| 1498 return "block-all-mixed-content"; | |
| 1499 case DirectiveType::ChildSrc: | |
| 1500 return "child-src"; | |
| 1501 case DirectiveType::ConnectSrc: | |
| 1502 return "connect-src"; | |
| 1503 case DirectiveType::DefaultSrc: | |
| 1504 return "default-src"; | |
| 1505 case DirectiveType::FrameAncestors: | |
| 1506 return "frame-ancestors"; | |
| 1507 case DirectiveType::FrameSrc: | |
| 1508 return "frame-src"; | |
| 1509 case DirectiveType::FontSrc: | |
| 1510 return "font-src"; | |
| 1511 case DirectiveType::FormAction: | |
| 1512 return "form-action"; | |
| 1513 case DirectiveType::ImgSrc: | |
| 1514 return "img-src"; | |
| 1515 case DirectiveType::ManifestSrc: | |
| 1516 return "manifest-src"; | |
| 1517 case DirectiveType::MediaSrc: | |
| 1518 return "media-src"; | |
| 1519 case DirectiveType::ObjectSrc: | |
| 1520 return "object-src"; | |
| 1521 case DirectiveType::PluginTypes: | |
| 1522 return "plugin-types"; | |
| 1523 case DirectiveType::ReportURI: | |
| 1524 return "report-uri"; | |
| 1525 case DirectiveType::RequireSRIFor: | |
| 1526 return "require-sri-for"; | |
| 1527 case DirectiveType::Sandbox: | |
| 1528 return "sandbox"; | |
| 1529 case DirectiveType::ScriptSrc: | |
| 1530 return "script-src"; | |
| 1531 case DirectiveType::StyleSrc: | |
| 1532 return "style-src"; | |
| 1533 case DirectiveType::TreatAsPublicAddress: | |
| 1534 return "treat-as-public-address"; | |
| 1535 case DirectiveType::UpgradeInsecureRequests: | |
| 1536 return "upgrade-insecure-requests"; | |
| 1537 case DirectiveType::WorkerSrc: | |
| 1538 return "worker-src"; | |
| 1539 case DirectiveType::Undefined: | |
| 1540 NOTREACHED(); | |
| 1541 return ""; | |
| 1542 } | |
| 1543 | |
| 1544 NOTREACHED(); | |
| 1545 return ""; | |
| 1546 } | |
| 1547 | |
| 1548 ContentSecurityPolicy::DirectiveType ContentSecurityPolicy::getDirectiveType( | |
| 1549 const String& name) { | |
| 1550 if (name == "base-uri") | |
| 1551 return DirectiveType::BaseURI; | |
| 1552 if (name == "block-all-mixed-content") | |
| 1553 return DirectiveType::BlockAllMixedContent; | |
| 1554 if (name == "child-src") | |
| 1555 return DirectiveType::ChildSrc; | |
| 1556 if (name == "connect-src") | |
| 1557 return DirectiveType::ConnectSrc; | |
| 1558 if (name == "default-src") | |
| 1559 return DirectiveType::DefaultSrc; | |
| 1560 if (name == "frame-ancestors") | |
| 1561 return DirectiveType::FrameAncestors; | |
| 1562 if (name == "frame-src") | |
| 1563 return DirectiveType::FrameSrc; | |
| 1564 if (name == "font-src") | |
| 1565 return DirectiveType::FontSrc; | |
| 1566 if (name == "form-action") | |
| 1567 return DirectiveType::FormAction; | |
| 1568 if (name == "img-src") | |
| 1569 return DirectiveType::ImgSrc; | |
| 1570 if (name == "manifest-src") | |
| 1571 return DirectiveType::ManifestSrc; | |
| 1572 if (name == "media-src") | |
| 1573 return DirectiveType::MediaSrc; | |
| 1574 if (name == "object-src") | |
| 1575 return DirectiveType::ObjectSrc; | |
| 1576 if (name == "plugin-types") | |
| 1577 return DirectiveType::PluginTypes; | |
| 1578 if (name == "report-uri") | |
| 1579 return DirectiveType::ReportURI; | |
| 1580 if (name == "require-sri-for") | |
| 1581 return DirectiveType::RequireSRIFor; | |
| 1582 if (name == "sandbox") | |
| 1583 return DirectiveType::Sandbox; | |
| 1584 if (name == "script-src") | |
| 1585 return DirectiveType::ScriptSrc; | |
| 1586 if (name == "style-src") | |
| 1587 return DirectiveType::StyleSrc; | |
| 1588 if (name == "treat-as-public-address") | |
| 1589 return DirectiveType::TreatAsPublicAddress; | |
| 1590 if (name == "upgrade-insecure-requests") | |
| 1591 return DirectiveType::UpgradeInsecureRequests; | |
| 1592 if (name == "worker-src") | |
| 1593 return DirectiveType::WorkerSrc; | |
| 1594 | |
| 1595 return DirectiveType::Undefined; | |
| 1596 } | |
| 1597 | |
| 1598 } // namespace blink | 1559 } // namespace blink |
| OLD | NEW |