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 819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 if (canSafelyExposeURL) { | 830 if (canSafelyExposeURL) { |
831 // 'KURL::strippedForUseAsReferrer()' dumps 'String()' for non-webby URL
s. | 831 // 'KURL::strippedForUseAsReferrer()' dumps 'String()' for non-webby URL
s. |
832 // It's better for developers if we return the origin of those URLs rath
er | 832 // It's better for developers if we return the origin of those URLs rath
er |
833 // than nothing. | 833 // than nothing. |
834 if (url.protocolIsInHTTPFamily()) | 834 if (url.protocolIsInHTTPFamily()) |
835 return url.strippedForUseAsReferrer(); | 835 return url.strippedForUseAsReferrer(); |
836 } | 836 } |
837 return SecurityOrigin::create(url)->toString(); | 837 return SecurityOrigin::create(url)->toString(); |
838 } | 838 } |
839 | 839 |
840 static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventI
nit& init, Document* document, const String& directiveText, const String& effect
iveDirective, const KURL& blockedURL, const String& header, RedirectStatus redir
ectStatus, ContentSecurityPolicy::ViolationType violationType, int contextLine) | 840 static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventI
nit& init, Document* document, const String& directiveText, ContentSecurityPolic
y::DispositionType dispositionType, const String& effectiveDirective, const KURL
& blockedURL, const String& header, RedirectStatus redirectStatus, ContentSecuri
tyPolicy::ViolationType violationType, int contextLine) |
841 { | 841 { |
842 if (equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::FrameAncest
ors)) { | 842 if (equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::FrameAncest
ors)) { |
843 // If this load was blocked via 'frame-ancestors', then the URL of |docu
ment| has not yet | 843 // If this load was blocked via 'frame-ancestors', then the URL of |docu
ment| has not yet |
844 // been initialized. In this case, we'll set both 'documentURI' and 'blo
ckedURI' to the | 844 // been initialized. In this case, we'll set both 'documentURI' and 'blo
ckedURI' to the |
845 // blocked document's URL. | 845 // blocked document's URL. |
846 init.setDocumentURI(blockedURL.getString()); | 846 init.setDocumentURI(blockedURL.getString()); |
847 init.setBlockedURI(blockedURL.getString()); | 847 init.setBlockedURI(blockedURL.getString()); |
848 } else { | 848 } else { |
849 init.setDocumentURI(document->url().getString()); | 849 init.setDocumentURI(document->url().getString()); |
850 switch (violationType) { | 850 switch (violationType) { |
851 case ContentSecurityPolicy::InlineViolation: | 851 case ContentSecurityPolicy::InlineViolation: |
852 init.setBlockedURI("inline"); | 852 init.setBlockedURI("inline"); |
853 break; | 853 break; |
854 case ContentSecurityPolicy::EvalViolation: | 854 case ContentSecurityPolicy::EvalViolation: |
855 init.setBlockedURI("eval"); | 855 init.setBlockedURI("eval"); |
856 break; | 856 break; |
857 case ContentSecurityPolicy::URLViolation: | 857 case ContentSecurityPolicy::URLViolation: |
858 init.setBlockedURI(stripURLForUseInReport(document, blockedURL, redi
rectStatus, effectiveDirective)); | 858 init.setBlockedURI(stripURLForUseInReport(document, blockedURL, redi
rectStatus, effectiveDirective)); |
859 break; | 859 break; |
860 } | 860 } |
861 } | 861 } |
862 init.setReferrer(document->referrer()); | 862 init.setReferrer(document->referrer()); |
863 init.setViolatedDirective(directiveText); | 863 init.setViolatedDirective(directiveText); |
864 init.setEffectiveDirective(effectiveDirective); | 864 init.setEffectiveDirective(effectiveDirective); |
865 init.setOriginalPolicy(header); | 865 init.setOriginalPolicy(header); |
| 866 switch (dispositionType) { |
| 867 case ContentSecurityPolicy::Enforce: |
| 868 init.setDisposition("enforce"); |
| 869 break; |
| 870 case ContentSecurityPolicy::Report: |
| 871 init.setDisposition("report"); |
| 872 break; |
| 873 } |
866 init.setSourceFile(String()); | 874 init.setSourceFile(String()); |
867 init.setLineNumber(contextLine); | 875 init.setLineNumber(contextLine); |
868 init.setColumnNumber(0); | 876 init.setColumnNumber(0); |
869 init.setStatusCode(0); | 877 init.setStatusCode(0); |
870 | 878 |
871 if (!SecurityOrigin::isSecure(document->url()) && document->loader()) | 879 if (!SecurityOrigin::isSecure(document->url()) && document->loader()) |
872 init.setStatusCode(document->loader()->response().httpStatusCode()); | 880 init.setStatusCode(document->loader()->response().httpStatusCode()); |
873 | 881 |
874 std::unique_ptr<SourceLocation> location = SourceLocation::capture(document)
; | 882 std::unique_ptr<SourceLocation> location = SourceLocation::capture(document)
; |
875 if (location->lineNumber()) { | 883 if (location->lineNumber()) { |
876 KURL source = KURL(ParsedURLString, location->url()); | 884 KURL source = KURL(ParsedURLString, location->url()); |
877 init.setSourceFile(stripURLForUseInReport(document, source, redirectStat
us, effectiveDirective)); | 885 init.setSourceFile(stripURLForUseInReport(document, source, redirectStat
us, effectiveDirective)); |
878 init.setLineNumber(location->lineNumber()); | 886 init.setLineNumber(location->lineNumber()); |
879 init.setColumnNumber(location->columnNumber()); | 887 init.setColumnNumber(location->columnNumber()); |
880 } | 888 } |
881 } | 889 } |
882 | 890 |
883 void ContentSecurityPolicy::reportViolation(const String& directiveText, const S
tring& effectiveDirective, const String& consoleMessage, const KURL& blockedURL,
const Vector<String>& reportEndpoints, const String& header, ViolationType viol
ationType, LocalFrame* contextFrame, RedirectStatus redirectStatus, int contextL
ine) | 891 void ContentSecurityPolicy::reportViolation(const String& directiveText, Disposi
tionType dispositionType, const String& effectiveDirective, const String& consol
eMessage, const KURL& blockedURL, const Vector<String>& reportEndpoints, const S
tring& header, ViolationType violationType, LocalFrame* contextFrame, RedirectSt
atus redirectStatus, int contextLine) |
884 { | 892 { |
885 ASSERT(violationType == URLViolation || blockedURL.isEmpty()); | 893 ASSERT(violationType == URLViolation || blockedURL.isEmpty()); |
886 | 894 |
887 // TODO(lukasza): Support sending reports from OOPIFs - https://crbug.com/61
1232 | 895 // TODO(lukasza): Support sending reports from OOPIFs - https://crbug.com/61
1232 |
888 // (or move CSP child-src and frame-src checks to the browser process - see | 896 // (or move CSP child-src and frame-src checks to the browser process - see |
889 // https://crbug.com/376522). | 897 // https://crbug.com/376522). |
890 if (!m_executionContext && !contextFrame) { | 898 if (!m_executionContext && !contextFrame) { |
891 DCHECK(equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::Chil
dSrc) | 899 DCHECK(equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::Chil
dSrc) |
892 || equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::Fram
eSrc) | 900 || equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::Fram
eSrc) |
893 || equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::Plug
inTypes)); | 901 || equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::Plug
inTypes)); |
894 return; | 902 return; |
895 } | 903 } |
896 | 904 |
897 ASSERT((m_executionContext && !contextFrame) || (equalIgnoringCase(effective
Directive, ContentSecurityPolicy::FrameAncestors) && contextFrame)); | 905 ASSERT((m_executionContext && !contextFrame) || (equalIgnoringCase(effective
Directive, ContentSecurityPolicy::FrameAncestors) && contextFrame)); |
898 | 906 |
899 // FIXME: Support sending reports from worker. | 907 // FIXME: Support sending reports from worker. |
900 Document* document = contextFrame ? contextFrame->document() : this->documen
t(); | 908 Document* document = contextFrame ? contextFrame->document() : this->documen
t(); |
901 if (!document) | 909 if (!document) |
902 return; | 910 return; |
903 | 911 |
904 SecurityPolicyViolationEventInit violationData; | 912 SecurityPolicyViolationEventInit violationData; |
905 gatherSecurityPolicyViolationEventData(violationData, document, directiveTex
t, effectiveDirective, blockedURL, header, redirectStatus, violationType, contex
tLine); | 913 gatherSecurityPolicyViolationEventData(violationData, document, directiveTex
t, dispositionType, effectiveDirective, blockedURL, header, redirectStatus, viol
ationType, contextLine); |
906 | 914 |
907 // TODO(mkwst): Obviously, we shouldn't hit this check, as extension-loaded | 915 // TODO(mkwst): Obviously, we shouldn't hit this check, as extension-loaded |
908 // resources should be allowed regardless. We apparently do, however, so | 916 // resources should be allowed regardless. We apparently do, however, so |
909 // we should at least stop spamming reporting endpoints. See | 917 // we should at least stop spamming reporting endpoints. See |
910 // https://crbug.com/524356 for detail. | 918 // https://crbug.com/524356 for detail. |
911 if (!violationData.sourceFile().isEmpty() && SchemeRegistry::schemeShouldByp
assContentSecurityPolicy(KURL(ParsedURLString, violationData.sourceFile()).proto
col())) | 919 if (!violationData.sourceFile().isEmpty() && SchemeRegistry::schemeShouldByp
assContentSecurityPolicy(KURL(ParsedURLString, violationData.sourceFile()).proto
col())) |
912 return; | 920 return; |
913 | 921 |
914 // We need to be careful here when deciding what information to send to the | 922 // We need to be careful here when deciding what information to send to the |
915 // report-uri. Currently, we send only the current document's URL and the | 923 // report-uri. Currently, we send only the current document's URL and the |
916 // directive that was violated. The document's URL is safe to send because | 924 // directive that was violated. The document's URL is safe to send because |
917 // it's the document itself that's requesting that it be sent. You could | 925 // it's the document itself that's requesting that it be sent. You could |
918 // make an argument that we shouldn't send HTTPS document URLs to HTTP | 926 // make an argument that we shouldn't send HTTPS document URLs to HTTP |
919 // report-uris (for the same reasons that we supress the Referer in that | 927 // report-uris (for the same reasons that we supress the Referer in that |
920 // case), but the Referer is sent implicitly whereas this request is only | 928 // case), but the Referer is sent implicitly whereas this request is only |
921 // sent explicitly. As for which directive was violated, that's pretty | 929 // sent explicitly. As for which directive was violated, that's pretty |
922 // harmless information. | 930 // harmless information. |
923 | 931 |
924 std::unique_ptr<JSONObject> cspReport = JSONObject::create(); | 932 std::unique_ptr<JSONObject> cspReport = JSONObject::create(); |
925 cspReport->setString("document-uri", violationData.documentURI()); | 933 cspReport->setString("document-uri", violationData.documentURI()); |
926 cspReport->setString("referrer", violationData.referrer()); | 934 cspReport->setString("referrer", violationData.referrer()); |
927 cspReport->setString("violated-directive", violationData.violatedDirective()
); | 935 cspReport->setString("violated-directive", violationData.violatedDirective()
); |
928 cspReport->setString("effective-directive", violationData.effectiveDirective
()); | 936 cspReport->setString("effective-directive", violationData.effectiveDirective
()); |
929 cspReport->setString("original-policy", violationData.originalPolicy()); | 937 cspReport->setString("original-policy", violationData.originalPolicy()); |
| 938 cspReport->setString("disposition", violationData.disposition()); |
930 cspReport->setString("blocked-uri", violationData.blockedURI()); | 939 cspReport->setString("blocked-uri", violationData.blockedURI()); |
931 if (violationData.lineNumber()) | 940 if (violationData.lineNumber()) |
932 cspReport->setInteger("line-number", violationData.lineNumber()); | 941 cspReport->setInteger("line-number", violationData.lineNumber()); |
933 if (violationData.columnNumber()) | 942 if (violationData.columnNumber()) |
934 cspReport->setInteger("column-number", violationData.columnNumber()); | 943 cspReport->setInteger("column-number", violationData.columnNumber()); |
935 if (!violationData.sourceFile().isEmpty()) | 944 if (!violationData.sourceFile().isEmpty()) |
936 cspReport->setString("source-file", violationData.sourceFile()); | 945 cspReport->setString("source-file", violationData.sourceFile()); |
937 cspReport->setInteger("status-code", violationData.statusCode()); | 946 cspReport->setInteger("status-code", violationData.statusCode()); |
938 | 947 |
939 std::unique_ptr<JSONObject> reportObject = JSONObject::create(); | 948 std::unique_ptr<JSONObject> reportObject = JSONObject::create(); |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 // Collisions have no security impact, so we can save space by storing only
the string's hash rather than the whole report. | 1171 // Collisions have no security impact, so we can save space by storing only
the string's hash rather than the whole report. |
1163 return !m_violationReportsSent.contains(report.impl()->hash()); | 1172 return !m_violationReportsSent.contains(report.impl()->hash()); |
1164 } | 1173 } |
1165 | 1174 |
1166 void ContentSecurityPolicy::didSendViolationReport(const String& report) | 1175 void ContentSecurityPolicy::didSendViolationReport(const String& report) |
1167 { | 1176 { |
1168 m_violationReportsSent.add(report.impl()->hash()); | 1177 m_violationReportsSent.add(report.impl()->hash()); |
1169 } | 1178 } |
1170 | 1179 |
1171 } // namespace blink | 1180 } // namespace blink |
OLD | NEW |