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 762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 return; | 773 return; |
774 m_treatAsPublicAddress = true; | 774 m_treatAsPublicAddress = true; |
775 } | 775 } |
776 | 776 |
777 void ContentSecurityPolicy::setInsecureRequestsPolicy(SecurityContext::InsecureR
equestsPolicy policy) | 777 void ContentSecurityPolicy::setInsecureRequestsPolicy(SecurityContext::InsecureR
equestsPolicy policy) |
778 { | 778 { |
779 if (policy > m_insecureRequestsPolicy) | 779 if (policy > m_insecureRequestsPolicy) |
780 m_insecureRequestsPolicy = policy; | 780 m_insecureRequestsPolicy = policy; |
781 } | 781 } |
782 | 782 |
783 static String stripURLForUseInReport(Document* document, const KURL& url) | 783 static String stripURLForUseInReport(Document* document, const KURL& url, Redire
ctStatus redirectStatus) |
784 { | 784 { |
785 if (!url.isValid()) | 785 if (!url.isValid()) |
786 return String(); | 786 return String(); |
787 if (!url.isHierarchical() || url.protocolIs("file")) | 787 if (!url.isHierarchical() || url.protocolIs("file")) |
788 return url.protocol(); | 788 return url.protocol(); |
789 return document->getSecurityOrigin()->canRequest(url) ? url.strippedForUseAs
Referrer() : SecurityOrigin::create(url)->toString(); | 789 if (redirectStatus == RedirectStatus::NoRedirect || document->getSecurityOri
gin()->canRequest(url)) { |
| 790 // 'KURL::strippedForUseAsReferrer()' dumps 'String()' for non-webby URL
s. |
| 791 // It's better for developers if we return the origin of those URLs rath
er |
| 792 // than nothing. |
| 793 if (url.protocolIsInHTTPFamily()) |
| 794 return url.strippedForUseAsReferrer(); |
| 795 } |
| 796 return SecurityOrigin::create(url)->toString(); |
790 } | 797 } |
791 | 798 |
792 static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventI
nit& init, Document* document, const String& directiveText, const String& effect
iveDirective, const KURL& blockedURL, const String& header) | 799 static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventI
nit& init, Document* document, const String& directiveText, const String& effect
iveDirective, const KURL& blockedURL, const String& header, RedirectStatus redir
ectStatus) |
793 { | 800 { |
794 if (equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::FrameAncest
ors)) { | 801 if (equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::FrameAncest
ors)) { |
795 // If this load was blocked via 'frame-ancestors', then the URL of |docu
ment| has not yet | 802 // If this load was blocked via 'frame-ancestors', then the URL of |docu
ment| has not yet |
796 // been initialized. In this case, we'll set both 'documentURI' and 'blo
ckedURI' to the | 803 // been initialized. In this case, we'll set both 'documentURI' and 'blo
ckedURI' to the |
797 // blocked document's URL. | 804 // blocked document's URL. |
798 init.setDocumentURI(blockedURL.getString()); | 805 init.setDocumentURI(blockedURL.getString()); |
799 init.setBlockedURI(blockedURL.getString()); | 806 init.setBlockedURI(blockedURL.getString()); |
800 } else { | 807 } else { |
801 init.setDocumentURI(document->url().getString()); | 808 init.setDocumentURI(document->url().getString()); |
802 init.setBlockedURI(stripURLForUseInReport(document, blockedURL)); | 809 init.setBlockedURI(stripURLForUseInReport(document, blockedURL, redirect
Status)); |
803 } | 810 } |
804 init.setReferrer(document->referrer()); | 811 init.setReferrer(document->referrer()); |
805 init.setViolatedDirective(directiveText); | 812 init.setViolatedDirective(directiveText); |
806 init.setEffectiveDirective(effectiveDirective); | 813 init.setEffectiveDirective(effectiveDirective); |
807 init.setOriginalPolicy(header); | 814 init.setOriginalPolicy(header); |
808 init.setSourceFile(String()); | 815 init.setSourceFile(String()); |
809 init.setLineNumber(0); | 816 init.setLineNumber(0); |
810 init.setColumnNumber(0); | 817 init.setColumnNumber(0); |
811 init.setStatusCode(0); | 818 init.setStatusCode(0); |
812 | 819 |
813 if (!SecurityOrigin::isSecure(document->url()) && document->loader()) | 820 if (!SecurityOrigin::isSecure(document->url()) && document->loader()) |
814 init.setStatusCode(document->loader()->response().httpStatusCode()); | 821 init.setStatusCode(document->loader()->response().httpStatusCode()); |
815 | 822 |
816 OwnPtr<SourceLocation> location = SourceLocation::capture(document); | 823 OwnPtr<SourceLocation> location = SourceLocation::capture(document); |
817 if (location->lineNumber()) { | 824 if (location->lineNumber()) { |
818 KURL source = KURL(ParsedURLString, location->url()); | 825 KURL source = KURL(ParsedURLString, location->url()); |
819 init.setSourceFile(stripURLForUseInReport(document, source)); | 826 init.setSourceFile(stripURLForUseInReport(document, source, redirectStat
us)); |
820 init.setLineNumber(location->lineNumber()); | 827 init.setLineNumber(location->lineNumber()); |
821 init.setColumnNumber(location->columnNumber()); | 828 init.setColumnNumber(location->columnNumber()); |
822 } | 829 } |
823 } | 830 } |
824 | 831 |
825 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) | 832 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) |
826 { | 833 { |
827 ASSERT(violationType == URLViolation || blockedURL.isEmpty()); | 834 ASSERT(violationType == URLViolation || blockedURL.isEmpty()); |
828 | 835 |
829 // TODO(lukasza): Support sending reports from OOPIFs - https://crbug.com/61
1232 | 836 // TODO(lukasza): Support sending reports from OOPIFs - https://crbug.com/61
1232 |
830 // (or move CSP child-src and frame-src checks to the browser process - see | 837 // (or move CSP child-src and frame-src checks to the browser process - see |
831 // https://crbug.com/376522). | 838 // https://crbug.com/376522). |
832 if (!m_executionContext && !contextFrame) { | 839 if (!m_executionContext && !contextFrame) { |
833 DCHECK(equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::Chil
dSrc) | 840 DCHECK(equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::Chil
dSrc) |
834 || equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::Fram
eSrc)); | 841 || equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::Fram
eSrc)); |
835 return; | 842 return; |
836 } | 843 } |
837 | 844 |
838 ASSERT((m_executionContext && !contextFrame) || (equalIgnoringCase(effective
Directive, ContentSecurityPolicy::FrameAncestors) && contextFrame)); | 845 ASSERT((m_executionContext && !contextFrame) || (equalIgnoringCase(effective
Directive, ContentSecurityPolicy::FrameAncestors) && contextFrame)); |
839 | 846 |
840 // FIXME: Support sending reports from worker. | 847 // FIXME: Support sending reports from worker. |
841 Document* document = contextFrame ? contextFrame->document() : this->documen
t(); | 848 Document* document = contextFrame ? contextFrame->document() : this->documen
t(); |
842 if (!document) | 849 if (!document) |
843 return; | 850 return; |
844 | 851 |
845 LocalFrame* frame = document->frame(); | 852 LocalFrame* frame = document->frame(); |
846 if (!frame) | 853 if (!frame) |
847 return; | 854 return; |
848 | 855 |
849 SecurityPolicyViolationEventInit violationData; | 856 SecurityPolicyViolationEventInit violationData; |
850 gatherSecurityPolicyViolationEventData(violationData, document, directiveTex
t, effectiveDirective, blockedURL, header); | 857 gatherSecurityPolicyViolationEventData(violationData, document, directiveTex
t, effectiveDirective, blockedURL, header, redirectStatus); |
851 | 858 |
852 frame->localDOMWindow()->enqueueDocumentEvent(SecurityPolicyViolationEvent::
create(EventTypeNames::securitypolicyviolation, violationData)); | 859 frame->localDOMWindow()->enqueueDocumentEvent(SecurityPolicyViolationEvent::
create(EventTypeNames::securitypolicyviolation, violationData)); |
853 | 860 |
854 if (reportEndpoints.isEmpty()) | 861 if (reportEndpoints.isEmpty()) |
855 return; | 862 return; |
856 | 863 |
857 // TODO(mkwst): Obviously, we shouldn't hit this check, as extension-loaded | 864 // TODO(mkwst): Obviously, we shouldn't hit this check, as extension-loaded |
858 // resources should be allowed regardless. We apparently do, however, so | 865 // resources should be allowed regardless. We apparently do, however, so |
859 // we should at least stop spamming reporting endpoints. See | 866 // we should at least stop spamming reporting endpoints. See |
860 // https://crbug.com/524356 for detail. | 867 // https://crbug.com/524356 for detail. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
910 // its URL with the blocked document's URL. | 917 // its URL with the blocked document's URL. |
911 ASSERT(!contextFrame || !m_executionContext); | 918 ASSERT(!contextFrame || !m_executionContext); |
912 ASSERT(!contextFrame || equalIgnoringCase(effectiveDirective, FrameAnces
tors)); | 919 ASSERT(!contextFrame || equalIgnoringCase(effectiveDirective, FrameAnces
tors)); |
913 KURL url = contextFrame ? frame->document()->completeURLWithOverride(end
point, blockedURL) : completeURL(endpoint); | 920 KURL url = contextFrame ? frame->document()->completeURLWithOverride(end
point, blockedURL) : completeURL(endpoint); |
914 PingLoader::sendViolationReport(frame, url, report, PingLoader::ContentS
ecurityPolicyViolationReport); | 921 PingLoader::sendViolationReport(frame, url, report, PingLoader::ContentS
ecurityPolicyViolationReport); |
915 } | 922 } |
916 | 923 |
917 didSendViolationReport(stringifiedReport); | 924 didSendViolationReport(stringifiedReport); |
918 } | 925 } |
919 | 926 |
920 void ContentSecurityPolicy::reportMixedContent(const KURL& mixedURL) | 927 void ContentSecurityPolicy::reportMixedContent(const KURL& mixedURL, RedirectSta
tus redirectStatus) |
921 { | 928 { |
922 for (const auto& policy : m_policies) | 929 for (const auto& policy : m_policies) |
923 policy->reportMixedContent(mixedURL); | 930 policy->reportMixedContent(mixedURL, redirectStatus); |
924 } | 931 } |
925 | 932 |
926 void ContentSecurityPolicy::reportInvalidReferrer(const String& invalidValue) | 933 void ContentSecurityPolicy::reportInvalidReferrer(const String& invalidValue) |
927 { | 934 { |
928 logToConsole("The 'referrer' Content Security Policy directive has the inval
id value \"" + invalidValue + "\". Valid values are \"no-referrer\", \"no-referr
er-when-downgrade\", \"origin\", \"origin-when-cross-origin\", and \"unsafe-url\
"."); | 935 logToConsole("The 'referrer' Content Security Policy directive has the inval
id value \"" + invalidValue + "\". Valid values are \"no-referrer\", \"no-referr
er-when-downgrade\", \"origin\", \"origin-when-cross-origin\", and \"unsafe-url\
"."); |
929 } | 936 } |
930 | 937 |
931 void ContentSecurityPolicy::reportReportOnlyInMeta(const String& header) | 938 void ContentSecurityPolicy::reportReportOnlyInMeta(const String& header) |
932 { | 939 { |
933 logToConsole("The report-only Content Security Policy '" + header + "' was d
elivered via a <meta> element, which is disallowed. The policy has been ignored.
"); | 940 logToConsole("The report-only Content Security Policy '" + header + "' was d
elivered via a <meta> element, which is disallowed. The policy has been ignored.
"); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1112 // Collisions have no security impact, so we can save space by storing only
the string's hash rather than the whole report. | 1119 // Collisions have no security impact, so we can save space by storing only
the string's hash rather than the whole report. |
1113 return !m_violationReportsSent.contains(report.impl()->hash()); | 1120 return !m_violationReportsSent.contains(report.impl()->hash()); |
1114 } | 1121 } |
1115 | 1122 |
1116 void ContentSecurityPolicy::didSendViolationReport(const String& report) | 1123 void ContentSecurityPolicy::didSendViolationReport(const String& report) |
1117 { | 1124 { |
1118 m_violationReportsSent.add(report.impl()->hash()); | 1125 m_violationReportsSent.add(report.impl()->hash()); |
1119 } | 1126 } |
1120 | 1127 |
1121 } // namespace blink | 1128 } // namespace blink |
OLD | NEW |