Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp

Issue 2056183002: Implement the `require-sri-for` CSP directive (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/frame/csp/CSPDirectiveList.h" 5 #include "core/frame/csp/CSPDirectiveList.h"
6 6
7 #include "bindings/core/v8/SourceLocation.h" 7 #include "bindings/core/v8/SourceLocation.h"
8 #include "core/dom/Document.h" 8 #include "core/dom/Document.h"
9 #include "core/dom/SecurityContext.h" 9 #include "core/dom/SecurityContext.h"
10 #include "core/dom/SpaceSplitString.h" 10 #include "core/dom/SpaceSplitString.h"
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 // 166 //
167 // TODO(mkwst): Move this check up into the browser process. See 167 // TODO(mkwst): Move this check up into the browser process. See
168 // https://crbug.com/555418. 168 // https://crbug.com/555418.
169 KURL url(KURL(), current->securityContext()->getSecurityOrigin()->toStri ng()); 169 KURL url(KURL(), current->securityContext()->getSecurityOrigin()->toStri ng());
170 if (!directive->allows(url, ResourceRequest::RedirectStatus::NoRedirect) ) 170 if (!directive->allows(url, ResourceRequest::RedirectStatus::NoRedirect) )
171 return false; 171 return false;
172 } 172 }
173 return true; 173 return true;
174 } 174 }
175 175
176 bool CSPDirectiveList::checkIntegrityPresence(WebURLRequest::RequestContext cont ext, const IntegrityMetadataSet& integrityMetadata) const
177 {
178 if (!integrityMetadata.isEmpty())
179 return true;
180
181 if (m_requireSRIFor.isEmpty())
182 return true;
183
184 for (const auto& token : m_requireSRIFor) {
185 if (equalIgnoringCase(token, "script")) {
186 if (context == WebURLRequest::RequestContextScript || context == Web URLRequest::RequestContextImport) {
187 if (integrityMetadata.isEmpty())
188 return false;
189 }
190 } else if (equalIgnoringCase(token, "style")) {
191 if (context == WebURLRequest::RequestContextStyle) {
192 if (integrityMetadata.isEmpty())
193 return false;
194 }
195 }
196 }
197 return true;
198 }
199
200 bool CSPDirectiveList::checkIntegrityPresenceAndReportViolation(WebURLRequest::R equestContext context, const KURL& url, const IntegrityMetadataSet& integrityMet adata) const
201 {
202 if (checkIntegrityPresence(context, integrityMetadata))
203 return true;
204 String resourceType;
205 if (context == WebURLRequest::RequestContextScript || context == WebURLReque st::RequestContextImport)
jww 2016/06/11 22:45:12 Treating RequestContextImport as guaranteed to be
Sergey Shekyan 2016/06/20 07:12:00 I inherited the logic that RequestContextImport is
Mike West 2016/06/20 08:11:37 Right. Contexts are from an earlier version of Fet
206 resourceType = "script";
207 else if (context == WebURLRequest::RequestContextStyle)
208 resourceType = "stylesheet";
209 reportViolation(ContentSecurityPolicy::RequireSRIFor, ContentSecurityPolicy: :RequireSRIFor, "Refused to load the " + resourceType + " '" + url.elidedString( ) + "' because 'require-sri-for' directive requires integrity attribute be prese nt for all " + resourceType + "s.", url, ResourceRequest::RedirectStatus::NoRedi rect);
Mike West 2016/06/10 09:25:15 `NoRedirect` probably isn't correct here, as I thi
Sergey Shekyan 2016/06/20 07:11:59 Acknowledged.
210 return denyIfEnforcingPolicy();
211 }
212
213 bool CSPDirectiveList::allowRequestWithoutMetadata(WebURLRequest::RequestContext context, const KURL& url, const IntegrityMetadataSet& integrityMetadata, Conten tSecurityPolicy::ReportingStatus reportingStatus) const
214 {
215 if (reportingStatus == ContentSecurityPolicy::SendReport) {
216 return checkIntegrityPresenceAndReportViolation(context, url, integrityM etadata);
217 }
218 return checkIntegrityPresence(context, integrityMetadata);
219 }
220
176 bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const Strin g& type, const String& typeAttribute) const 221 bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const Strin g& type, const String& typeAttribute) const
177 { 222 {
178 if (!directive) 223 if (!directive)
179 return true; 224 return true;
180 if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type) 225 if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type)
181 return false; 226 return false;
182 return directive->allows(type); 227 return directive->allows(type);
183 } 228 }
184 229
185 SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* d irective) const 230 SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* d irective) const
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 } 589 }
545 590
546 // The directive-value may be empty. 591 // The directive-value may be empty.
547 if (valueBegin == position) 592 if (valueBegin == position)
548 return true; 593 return true;
549 594
550 value = String(valueBegin, position - valueBegin); 595 value = String(valueBegin, position - valueBegin);
551 return true; 596 return true;
552 } 597 }
553 598
599 void CSPDirectiveList::parseRequireSRIFor(const String& name, const String& valu e)
600 {
601 if (!m_requireSRIFor.isEmpty()) {
602 m_policy->reportDuplicateDirective(name);
603 return;
604 }
605 StringBuilder tokenErrors;
606 StringBuilder validTokens;
607 unsigned numberOfTokenErrors = 0;
608 Vector<UChar> characters;
609 value.appendTo(characters);
610
611 const UChar* position = characters.data();
612 const UChar* end = position + characters.size();
613
614 while (position < end) {
615 skipWhile<UChar, isASCIISpace>(position, end);
616
617 const UChar* tokenBegin = position;
618 skipWhile<UChar, isNotASCIISpace>(position, end);
619
620 if (tokenBegin < position) {
621 String token = String(tokenBegin, position - tokenBegin);
622 if (equalIgnoringCase(token, "script") || equalIgnoringCase(token, " style")) {
623 m_requireSRIFor.append(token);
624 if (!validTokens.isEmpty())
625 validTokens.append(' ');
626 validTokens.append(token);
627 } else {
628 if (numberOfTokenErrors)
629 tokenErrors.append(", \'");
630 else
631 tokenErrors.append('\'');
632 tokenErrors.append(token);
633 tokenErrors.append('\'');
634 numberOfTokenErrors++;
635 }
636 }
637 }
638
639 if (numberOfTokenErrors == 0)
640 return;
641
642 String invalidTokensErrorMessage;
643 if (numberOfTokenErrors > 1)
644 tokenErrors.append(" are invalid 'require-sri-for' tokens.");
645 else
646 tokenErrors.append(" is an invalid 'require-sri-for' token.");
647
648 invalidTokensErrorMessage = tokenErrors.toString();
649
650 if (!invalidTokensErrorMessage.isEmpty()) {
jww 2016/06/11 22:45:12 I think inavildTokensErrorMessage cannot be empty
Sergey Shekyan 2016/06/20 07:12:00 Acknowledged.
651 m_policy->reportInvalidRequireSRIForTokens(invalidTokensErrorMessage);
652 }
653 }
654
554 void CSPDirectiveList::parseReportURI(const String& name, const String& value) 655 void CSPDirectiveList::parseReportURI(const String& name, const String& value)
555 { 656 {
556 if (!m_reportEndpoints.isEmpty()) { 657 if (!m_reportEndpoints.isEmpty()) {
557 m_policy->reportDuplicateDirective(name); 658 m_policy->reportDuplicateDirective(name);
558 return; 659 return;
559 } 660 }
560 661
561 // Remove report-uri in meta policies, per https://www.w3.org/TR/CSP2/#deliv ery-html-meta-element. 662 // Remove report-uri in meta policies, per https://www.w3.org/TR/CSP2/#deliv ery-html-meta-element.
562 if (m_headerSource == ContentSecurityPolicyHeaderSourceMeta) { 663 if (m_headerSource == ContentSecurityPolicyHeaderSourceMeta) {
563 UseCounter::count(m_policy->document(), UseCounter::InvalidReportUriDire ctiveInMetaCSP); 664 UseCounter::count(m_policy->document(), UseCounter::InvalidReportUriDire ctiveInMetaCSP);
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 } else if (equalIgnoringCase(name, ContentSecurityPolicy::Referrer)) { 918 } else if (equalIgnoringCase(name, ContentSecurityPolicy::Referrer)) {
818 parseReferrer(name, value); 919 parseReferrer(name, value);
819 } else if (equalIgnoringCase(name, ContentSecurityPolicy::UpgradeInsecureReq uests)) { 920 } else if (equalIgnoringCase(name, ContentSecurityPolicy::UpgradeInsecureReq uests)) {
820 enableInsecureRequestsUpgrade(name, value); 921 enableInsecureRequestsUpgrade(name, value);
821 } else if (equalIgnoringCase(name, ContentSecurityPolicy::BlockAllMixedConte nt)) { 922 } else if (equalIgnoringCase(name, ContentSecurityPolicy::BlockAllMixedConte nt)) {
822 enforceStrictMixedContentChecking(name, value); 923 enforceStrictMixedContentChecking(name, value);
823 } else if (equalIgnoringCase(name, ContentSecurityPolicy::ManifestSrc)) { 924 } else if (equalIgnoringCase(name, ContentSecurityPolicy::ManifestSrc)) {
824 setCSPDirective<SourceListDirective>(name, value, m_manifestSrc); 925 setCSPDirective<SourceListDirective>(name, value, m_manifestSrc);
825 } else if (equalIgnoringCase(name, ContentSecurityPolicy::TreatAsPublicAddre ss)) { 926 } else if (equalIgnoringCase(name, ContentSecurityPolicy::TreatAsPublicAddre ss)) {
826 treatAsPublicAddress(name, value); 927 treatAsPublicAddress(name, value);
928 } else if (equalIgnoringCase(name, ContentSecurityPolicy::RequireSRIFor)) {
929 parseRequireSRIFor(name, value);
Mike West 2016/06/10 09:25:15 This functionality should be hidden behind the exp
Sergey Shekyan 2016/06/20 07:12:00 Acknowledged.
827 } else { 930 } else {
828 m_policy->reportUnsupportedDirective(name); 931 m_policy->reportUnsupportedDirective(name);
829 } 932 }
830 } 933 }
831 934
832 DEFINE_TRACE(CSPDirectiveList) 935 DEFINE_TRACE(CSPDirectiveList)
833 { 936 {
834 visitor->trace(m_policy); 937 visitor->trace(m_policy);
835 visitor->trace(m_pluginTypes); 938 visitor->trace(m_pluginTypes);
836 visitor->trace(m_baseURI); 939 visitor->trace(m_baseURI);
837 visitor->trace(m_childSrc); 940 visitor->trace(m_childSrc);
838 visitor->trace(m_connectSrc); 941 visitor->trace(m_connectSrc);
839 visitor->trace(m_defaultSrc); 942 visitor->trace(m_defaultSrc);
840 visitor->trace(m_fontSrc); 943 visitor->trace(m_fontSrc);
841 visitor->trace(m_formAction); 944 visitor->trace(m_formAction);
842 visitor->trace(m_frameAncestors); 945 visitor->trace(m_frameAncestors);
843 visitor->trace(m_frameSrc); 946 visitor->trace(m_frameSrc);
844 visitor->trace(m_imgSrc); 947 visitor->trace(m_imgSrc);
845 visitor->trace(m_mediaSrc); 948 visitor->trace(m_mediaSrc);
846 visitor->trace(m_manifestSrc); 949 visitor->trace(m_manifestSrc);
847 visitor->trace(m_objectSrc); 950 visitor->trace(m_objectSrc);
848 visitor->trace(m_scriptSrc); 951 visitor->trace(m_scriptSrc);
849 visitor->trace(m_styleSrc); 952 visitor->trace(m_styleSrc);
850 } 953 }
851 954
852 955
853 } // namespace blink 956 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698