Changeset 196012 in webkit
- Timestamp:
- Feb 2, 2016 9:57:40 AM (8 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r196010 r196012 1 2016-02-02 Daniel Bates <dabates@apple.com> 2 3 CSP: Support checking content security policy without a script execution context 4 https://bugs.webkit.org/show_bug.cgi?id=153748 5 <rdar://problem/24439149> 6 7 Reviewed by Darin Alder. 8 9 Towards checking a Web Worker's content security policy against a redirected worker 10 script load or redirected XHR request for an XHR request initiated from it, we should 11 support instantiating a ContentSecurityPolicy object without a ScriptExecutionContext. 12 13 No functionality was changed. So, no new tests. 14 15 * dom/Document.cpp: 16 (WebCore::Document::initSecurityContext): Pass |this| as a reference instead of as a pointer. 17 * page/csp/ContentSecurityPolicy.cpp: Remove extraneous includes ScriptState.h, TextEncoding.h, 18 and URL.h as they are included by ContentSecurityPolicy.h, FormDataList.h and FormData.h, respectively. 19 (WebCore::CSPSource::CSPSource): Take a constant reference to a ContentSecurityPolicy instead 20 of a pointer since we never expected a null pointer. 21 (WebCore::CSPSource::schemeMatches): Move logic for checking the protocol of source "self" 22 from here to ContentSecurityPolicy::protocolMatchesSelf() because we may not have a security 23 origin if ContentSecurityPolicy was initiated without a ScriptExecutionContext object. 24 (WebCore::CSPSourceList::allowSelf): Added. 25 (WebCore::CSPSourceList::CSPSourceList): Take a constant reference to a ContentSecurityPolicy 26 instead of a pointer since we never expected a null pointer. Remove fields from member 27 initialization list that can be initialized using C++11 in-class initialization syntax. 28 (WebCore::CSPSourceList::matches): Call ContentSecurityPolicy::urlMatchesSelf() to match the 29 effective URL against the URL of source "self". 30 (WebCore::CSPSourceList::parse): Update code as necessary now that m_policy is a reference 31 instead of a pointer. 32 (WebCore::CSPSourceList::parseSource): Simplify code by setting internal member fields directly 33 instead of via member functions. 34 (WebCore::CSPSourceList::parsePath): Update code as necessary now that m_policy is a reference 35 instead of a pointer. 36 (WebCore::CSPDirective::CSPDirective): Take a constant reference to a ContentSecurityPolicy 37 instead of a pointer since we never expected a null pointer. 38 (WebCore::CSPDirective::policy): Return a reference to a const ContentSecurityPolicy. 39 (WebCore::MediaListDirective::MediaListDirective): Take a constant reference to a ContentSecurityPolicy 40 instead of a pointer since we never expected a null pointer. 41 (WebCore::MediaListDirective::parse): Update code as necessary now that m_policy is a reference 42 instead of a pointer. 43 (WebCore::SourceListDirective::SourceListDirective): Take a constant reference to a ContentSecurityPolicy 44 instead of a pointer since we never expected a null pointer. 45 (WebCore::SourceListDirective::allows): Write in terms of CSPSourceList::allowSelf() because we 46 may not have a security origin to get a URL from if ContentSecurityPolicy was initiated without 47 a ScriptExecutionContext object. 48 (WebCore::CSPDirectiveList::reportURIs): Change return type from Vector<URL> to Vector<String> 49 The caller will convert the strings to URLs with respect to the script execution context. 50 (WebCore::CSPDirectiveList::parseReportURI): Store the report URI as a string instead of a URL 51 because we may not have a security origin to compute the absolute URL if ContentSecurityPolicy 52 was initiated without a ScriptExecutionContext object. 53 (WebCore::CSPDirectiveList::CSPDirectiveList): Take a reference to a ContentSecurityPolicy 54 instead of a pointer since we never expected a null pointer. It would be better to take a const 55 reference to a ContentSecurityPolicy, but ContentSecurityPolicy::applySandboxPolicy() needs to set 56 state on ContentSecurityPolicy :( 57 (WebCore::CSPDirectiveList::create): Ditto. 58 (WebCore::CSPDirectiveList::reportViolation): Update code as necessary now that m_policy is a reference 59 instead of a pointer. 60 (WebCore::CSPDirectiveList::checkEvalAndReportViolation): Ditto. 61 (WebCore::CSPDirectiveList::checkInlineAndReportViolation): Ditto. 62 (WebCore::CSPDirectiveList::parseDirective): Ditto. 63 (WebCore::CSPDirectiveList::parseReportURI): Store the report URI as a string instead of a URL 64 because we may not have a security origin to compute the absolute URL if ContentSecurityPolicy 65 was initiated without a ScriptExecutionContext object. 66 (WebCore::CSPDirectiveList::setCSPDirective): Update code as necessary now that m_policy is a reference 67 instead of a pointer. 68 (WebCore::CSPDirectiveList::applySandboxPolicy): Ditto. 69 (WebCore::CSPDirectiveList::parseReflectedXSS): Ditto. 70 (WebCore::CSPDirectiveList::addDirective): Ditto. 71 (WebCore::ContentSecurityPolicy::ContentSecurityPolicy): Modified to take the ScriptExecutionObject 72 as a reference and compute the CSPSource object for "self" and cache the protocol for "self". Removed 73 field m_overrideInlineStyleAllowed from the member initialization list and used C++11 in-class 74 initialization syntax to initialize it. Added overloaded constructor that takes a SecurityOrigin object. 75 We are not making use of this overloaded constructor at this time. We will in a subsequent patch. 76 (WebCore::ContentSecurityPolicy::didReceiveHeader): Store the eval disabled error message for 77 the last parsed policy in a member field instead of using it as part of disabling eval execution 78 on the script execution context because we may not have such a context. 79 (WebCore::ContentSecurityPolicy::applyPolicyToScriptExecutionContext): Applies the content security 80 policy eval and sandbox restrictions to the script execution context. 81 (WebCore::ContentSecurityPolicy::urlMatchesSelf): Match the specified URL against the URL for 82 source "self". 83 (WebCore::ContentSecurityPolicy::protocolMatchesSelf): Match the protocol of the specified URL 84 against the protocol for source "self". 85 (WebCore::ContentSecurityPolicy::gatherReportURIs): Modified to use the script execution context 86 to compute the absolute URL for each report URI. 87 (WebCore::ContentSecurityPolicy::reportViolation): Bail out if we do not have a script execution 88 context. 89 (WebCore::ContentSecurityPolicy::logToConsole): Only log to the console if we have a script 90 execution context. 91 (WebCore::ContentSecurityPolicy::reportBlockedScriptExecutionToInspector): Only report blocked 92 script execution to the Web Inspector if we have a script execution context. 93 (WebCore::CSPSourceList::addSourceSelf): Deleted. 94 (WebCore::CSPSourceList::addSourceStar): Deleted. 95 (WebCore::CSPSourceList::addSourceUnsafeInline): Deleted. 96 (WebCore::CSPSourceList::addSourceUnsafeEval): Deleted. 97 (WebCore::CSPDirectiveList::gatherReportURIs): Deleted. 98 (WebCore::ContentSecurityPolicy::securityOrigin): Deleted. 99 (WebCore::ContentSecurityPolicy::url): Deleted. 100 (WebCore::ContentSecurityPolicy::completeURL): Deleted. 101 (WebCore::ContentSecurityPolicy::enforceSandboxFlags): Deleted. 102 * page/csp/ContentSecurityPolicy.h: 103 (WebCore::ContentSecurityPolicy::enforceSandboxFlags): Accumulates the parsed sandbox flags. We 104 will apply the sandbox flags in ContentSecurityPolicy::applyPolicyToScriptExecutionContext(). 105 * workers/WorkerGlobalScope.cpp: 106 (WebCore::WorkerGlobalScope::WorkerGlobalScope): Instantiate ContentSecurityPolicy. 107 (WebCore::WorkerGlobalScope::applyContentSecurityPolicyResponseHeaders): Move instantiation of 108 ContentSecurityPolicy from here to constructor. 109 1 110 2016-02-02 Eric Carlson <eric.carlson@apple.com> 2 111 -
trunk/Source/WebCore/dom/Document.cpp
r195951 r196012 5129 5129 setCookieURL(URL(ParsedURLString, emptyString())); 5130 5130 setSecurityOriginPolicy(SecurityOriginPolicy::create(SecurityOrigin::createUnique())); 5131 setContentSecurityPolicy(std::make_unique<ContentSecurityPolicy>( this));5131 setContentSecurityPolicy(std::make_unique<ContentSecurityPolicy>(*this)); 5132 5132 return; 5133 5133 } … … 5142 5142 5143 5143 setSecurityOriginPolicy(SecurityOriginPolicy::create(isSandboxed(SandboxOrigin) ? SecurityOrigin::createUnique() : SecurityOrigin::create(m_url))); 5144 setContentSecurityPolicy(std::make_unique<ContentSecurityPolicy>( this));5144 setContentSecurityPolicy(std::make_unique<ContentSecurityPolicy>(*this)); 5145 5145 5146 5146 if (Settings* settings = this->settings()) { -
trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
r195948 r196012 39 39 #include "SchemeRegistry.h" 40 40 #include "ScriptController.h" 41 #include "ScriptState.h"42 41 #include "SecurityOrigin.h" 43 42 #include "SecurityPolicyViolationEvent.h" 44 #include "TextEncoding.h"45 #include "URL.h"46 43 #include <inspector/InspectorValues.h> 47 44 #include <inspector/ScriptCallStack.h> … … 216 213 class CSPSource { 217 214 public: 218 CSPSource( ContentSecurityPolicy*policy, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard)215 CSPSource(const ContentSecurityPolicy& policy, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard) 219 216 : m_policy(policy) 220 217 , m_scheme(scheme) … … 239 236 bool schemeMatches(const URL& url) const 240 237 { 241 if (m_scheme.isEmpty()) { 242 String protectedResourceScheme(m_policy->securityOrigin()->protocol()); 243 #if ENABLE(CSP_NEXT) 244 if (equalLettersIgnoringASCIICase(protectedResourceScheme, "http")) 245 return url.protocolIsInHTTPFamily(); 246 #endif 247 return equalIgnoringASCIICase(url.protocol(), protectedResourceScheme); 248 } 238 if (m_scheme.isEmpty()) 239 return m_policy.protocolMatchesSelf(url); 249 240 return equalIgnoringASCIICase(url.protocol(), m_scheme); 250 241 } … … 293 284 bool isSchemeOnly() const { return m_host.isEmpty(); } 294 285 295 ContentSecurityPolicy*m_policy;286 const ContentSecurityPolicy& m_policy; 296 287 String m_scheme; 297 288 String m_host; … … 305 296 class CSPSourceList { 306 297 public: 307 CSPSourceList( ContentSecurityPolicy*, const String& directiveName);298 CSPSourceList(const ContentSecurityPolicy&, const String& directiveName); 308 299 309 300 void parse(const String&); … … 311 302 bool allowInline() const { return m_allowInline; } 312 303 bool allowEval() const { return m_allowEval; } 304 bool allowSelf() const { return m_allowSelf; } 313 305 314 306 private: … … 321 313 bool parsePath(const UChar* begin, const UChar* end, String& path); 322 314 323 void addSourceSelf(); 324 void addSourceStar(); 325 void addSourceUnsafeInline(); 326 void addSourceUnsafeEval(); 327 328 ContentSecurityPolicy* m_policy; 315 const ContentSecurityPolicy& m_policy; 329 316 Vector<CSPSource> m_list; 330 317 String m_directiveName; 331 bool m_allowStar; 332 bool m_allowInline; 333 bool m_allowEval; 318 bool m_allowSelf { false }; 319 bool m_allowStar { false }; 320 bool m_allowInline { false }; 321 bool m_allowEval { false }; 334 322 }; 335 323 336 CSPSourceList::CSPSourceList( ContentSecurityPolicy*policy, const String& directiveName)324 CSPSourceList::CSPSourceList(const ContentSecurityPolicy& policy, const String& directiveName) 337 325 : m_policy(policy) 338 326 , m_directiveName(directiveName) 339 , m_allowStar(false)340 , m_allowInline(false)341 , m_allowEval(false)342 327 { 343 328 } … … 358 343 359 344 URL effectiveURL = SecurityOrigin::shouldUseInnerURL(url) ? SecurityOrigin::extractInnerURL(url) : url; 345 346 if (m_allowSelf && m_policy.urlMatchesSelf(effectiveURL)) 347 return true; 360 348 361 349 for (auto& entry : m_list) { … … 394 382 continue; 395 383 if (isDirectiveName(host)) 396 m_policy ->reportDirectiveAsSourceExpression(m_directiveName, host);384 m_policy.reportDirectiveAsSourceExpression(m_directiveName, host); 397 385 m_list.append(CSPSource(m_policy, scheme, host, port, path, hostHasWildcard, portHasWildcard)); 398 386 } else 399 m_policy ->reportInvalidSourceExpression(m_directiveName, String(beginSource, position - beginSource));387 m_policy.reportInvalidSourceExpression(m_directiveName, String(beginSource, position - beginSource)); 400 388 401 389 ASSERT(position == end || isASCIISpace(*position)); … … 416 404 417 405 if (end - begin == 1 && *begin == '*') { 418 addSourceStar();406 m_allowStar = true; 419 407 return true; 420 408 } 421 409 422 410 if (equalLettersIgnoringASCIICase(begin, end - begin, "'self'")) { 423 addSourceSelf();411 m_allowSelf = true; 424 412 return true; 425 413 } 426 414 427 415 if (equalLettersIgnoringASCIICase(begin, end - begin, "'unsafe-inline'")) { 428 addSourceUnsafeInline();416 m_allowInline = true; 429 417 return true; 430 418 } 431 419 432 420 if (equalLettersIgnoringASCIICase(begin, end - begin, "'unsafe-eval'")) { 433 addSourceUnsafeEval();421 m_allowEval = true; 434 422 return true; 435 423 } … … 591 579 // ^ ^ 592 580 if (position < end) 593 m_policy ->reportInvalidPathCharacter(m_directiveName, String(begin, end - begin), *position);581 m_policy.reportInvalidPathCharacter(m_directiveName, String(begin, end - begin), *position); 594 582 595 583 path = decodeURLEscapeSequences(String(begin, position - begin)); … … 631 619 } 632 620 633 void CSPSourceList::addSourceSelf()634 {635 m_list.append(CSPSource(m_policy, m_policy->securityOrigin()->protocol(), m_policy->securityOrigin()->host(), m_policy->securityOrigin()->port(), String(), false, false));636 }637 638 void CSPSourceList::addSourceStar()639 {640 m_allowStar = true;641 }642 643 void CSPSourceList::addSourceUnsafeInline()644 {645 m_allowInline = true;646 }647 648 void CSPSourceList::addSourceUnsafeEval()649 {650 m_allowEval = true;651 }652 653 621 class CSPDirective { 654 622 public: 655 CSPDirective(const String& name, const String& value, ContentSecurityPolicy*policy)623 CSPDirective(const String& name, const String& value, const ContentSecurityPolicy& policy) 656 624 : m_name(name) 657 625 , m_text(name + ' ' + value) … … 663 631 664 632 protected: 665 const ContentSecurityPolicy *policy() const { return m_policy; }633 const ContentSecurityPolicy& policy() const { return m_policy; } 666 634 667 635 private: 668 636 String m_name; 669 637 String m_text; 670 ContentSecurityPolicy*m_policy;638 const ContentSecurityPolicy& m_policy; 671 639 }; 672 640 673 641 class MediaListDirective : public CSPDirective { 674 642 public: 675 MediaListDirective(const String& name, const String& value, ContentSecurityPolicy*policy)643 MediaListDirective(const String& name, const String& value, const ContentSecurityPolicy& policy) 676 644 : CSPDirective(name, value, policy) 677 645 { … … 694 662 // 'plugin-types ____;' OR 'plugin-types;' 695 663 if (value.isEmpty()) { 696 policy() ->reportInvalidPluginTypes(value);664 policy().reportInvalidPluginTypes(value); 697 665 return; 698 666 } … … 710 678 if (!skipExactly<isMediaTypeCharacter>(position, end)) { 711 679 skipWhile<isNotASCIISpace>(position, end); 712 policy() ->reportInvalidPluginTypes(String(begin, position - begin));680 policy().reportInvalidPluginTypes(String(begin, position - begin)); 713 681 continue; 714 682 } … … 719 687 if (!skipExactly(position, end, '/')) { 720 688 skipWhile<isNotASCIISpace>(position, end); 721 policy() ->reportInvalidPluginTypes(String(begin, position - begin));689 policy().reportInvalidPluginTypes(String(begin, position - begin)); 722 690 continue; 723 691 } … … 727 695 if (!skipExactly<isMediaTypeCharacter>(position, end)) { 728 696 skipWhile<isNotASCIISpace>(position, end); 729 policy() ->reportInvalidPluginTypes(String(begin, position - begin));697 policy().reportInvalidPluginTypes(String(begin, position - begin)); 730 698 continue; 731 699 } … … 736 704 if (position < end && isNotASCIISpace(*position)) { 737 705 skipWhile<isNotASCIISpace>(position, end); 738 policy() ->reportInvalidPluginTypes(String(begin, position - begin));706 policy().reportInvalidPluginTypes(String(begin, position - begin)); 739 707 continue; 740 708 } … … 750 718 class SourceListDirective : public CSPDirective { 751 719 public: 752 SourceListDirective(const String& name, const String& value, ContentSecurityPolicy*policy)720 SourceListDirective(const String& name, const String& value, const ContentSecurityPolicy& policy) 753 721 : CSPDirective(name, value, policy) 754 722 , m_sourceList(policy, name) … … 759 727 bool allows(const URL& url) 760 728 { 761 return m_sourceList.matches(url.isEmpty() ? policy()->url() : url); 729 // FIXME: We should investigate returning false for an empty URL. 730 if (url.isEmpty()) 731 return m_sourceList.allowSelf(); 732 return m_sourceList.matches(url); 762 733 } 763 734 … … 772 743 WTF_MAKE_FAST_ALLOCATED; 773 744 public: 774 static std::unique_ptr<CSPDirectiveList> create(ContentSecurityPolicy *, const String&, ContentSecurityPolicyHeaderType);775 CSPDirectiveList(ContentSecurityPolicy *, ContentSecurityPolicyHeaderType);745 static std::unique_ptr<CSPDirectiveList> create(ContentSecurityPolicy&, const String&, ContentSecurityPolicyHeaderType); 746 CSPDirectiveList(ContentSecurityPolicy&, ContentSecurityPolicyHeaderType); 776 747 777 748 const String& header() const { return m_header; } … … 796 767 bool allowBaseURI(const URL&, ContentSecurityPolicy::ReportingStatus) const; 797 768 798 void gatherReportURIs(DOMStringList&) const;799 769 const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; } 800 770 ContentSecurityPolicy::ReflectedXSSDisposition reflectedXSSDisposition() const { return m_reflectedXSSDisposition; } 801 771 bool isReportOnly() const { return m_reportOnly; } 802 const Vector< URL>& reportURIs() const { return m_reportURIs; }772 const Vector<String>& reportURIs() const { return m_reportURIs; } 803 773 804 774 private: … … 833 803 bool denyIfEnforcingPolicy() const { return m_reportOnly; } 834 804 835 ContentSecurityPolicy* m_policy; 805 // FIXME: Make this a const reference once we teach applySandboxPolicy() to store its policy as opposed to applying it directly onto ContentSecurityPolicy. 806 ContentSecurityPolicy& m_policy; 836 807 837 808 String m_header; … … 855 826 std::unique_ptr<SourceListDirective> m_styleSrc; 856 827 857 Vector< URL> m_reportURIs;828 Vector<String> m_reportURIs; 858 829 859 830 String m_evalDisabledErrorMessage; 860 831 }; 861 832 862 CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy *policy, ContentSecurityPolicyHeaderType type)833 CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy& policy, ContentSecurityPolicyHeaderType type) 863 834 : m_policy(policy) 864 835 , m_headerType(type) … … 870 841 } 871 842 872 std::unique_ptr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy *policy, const String& header, ContentSecurityPolicyHeaderType type)843 std::unique_ptr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy& policy, const String& header, ContentSecurityPolicyHeaderType type) 873 844 { 874 845 auto directives = std::make_unique<CSPDirectiveList>(policy, type); … … 881 852 882 853 if (directives->isReportOnly() && directives->reportURIs().isEmpty()) 883 policy ->reportMissingReportURI(header);854 policy.reportMissingReportURI(header); 884 855 885 856 return directives; … … 889 860 { 890 861 String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage; 891 m_policy ->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header, contextURL, contextLine, state);862 m_policy.reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header, contextURL, contextLine, state); 892 863 } 893 864 … … 932 903 reportViolation(directive->text(), scriptSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", URL(), contextURL, contextLine, state); 933 904 if (!m_reportOnly) { 934 m_policy ->reportBlockedScriptExecutionToInspector(directive->text());905 m_policy.reportBlockedScriptExecutionToInspector(directive->text()); 935 906 return false; 936 907 } … … 964 935 if (!m_reportOnly) { 965 936 if (isScript) 966 m_policy ->reportBlockedScriptExecutionToInspector(directive->text());937 m_policy.reportBlockedScriptExecutionToInspector(directive->text()); 967 938 return false; 968 939 } … … 1114 1085 } 1115 1086 1116 void CSPDirectiveList::gatherReportURIs(DOMStringList& list) const1117 {1118 for (auto& uri : m_reportURIs)1119 list.append(uri.string());1120 }1121 1122 1087 bool CSPDirectiveList::allowFormAction(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const 1123 1088 { … … 1184 1149 if (nameBegin == position) { 1185 1150 skipWhile<isNotASCIISpace>(position, end); 1186 m_policy ->reportUnsupportedDirective(String(nameBegin, position - nameBegin));1151 m_policy.reportUnsupportedDirective(String(nameBegin, position - nameBegin)); 1187 1152 return false; 1188 1153 } … … 1195 1160 if (!skipExactly<isASCIISpace>(position, end)) { 1196 1161 skipWhile<isNotASCIISpace>(position, end); 1197 m_policy ->reportUnsupportedDirective(String(nameBegin, position - nameBegin));1162 m_policy.reportUnsupportedDirective(String(nameBegin, position - nameBegin)); 1198 1163 return false; 1199 1164 } … … 1205 1170 1206 1171 if (position != end) { 1207 m_policy ->reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin));1172 m_policy.reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin)); 1208 1173 return false; 1209 1174 } … … 1220 1185 { 1221 1186 if (!m_reportURIs.isEmpty()) { 1222 m_policy ->reportDuplicateDirective(name);1187 m_policy.reportDuplicateDirective(name); 1223 1188 return; 1224 1189 } … … 1234 1199 skipWhile<isNotASCIISpace>(position, end); 1235 1200 1236 if (urlBegin < position) { 1237 String url = String(urlBegin, position - urlBegin); 1238 m_reportURIs.append(m_policy->completeURL(url)); 1239 } 1201 if (urlBegin < position) 1202 m_reportURIs.append(value.substring(urlBegin - characters, position - urlBegin)); 1240 1203 } 1241 1204 } … … 1246 1209 { 1247 1210 if (directive) { 1248 m_policy ->reportDuplicateDirective(name);1211 m_policy.reportDuplicateDirective(name); 1249 1212 return; 1250 1213 } … … 1255 1218 { 1256 1219 if (m_haveSandboxPolicy) { 1257 m_policy ->reportDuplicateDirective(name);1220 m_policy.reportDuplicateDirective(name); 1258 1221 return; 1259 1222 } 1260 1223 m_haveSandboxPolicy = true; 1261 1224 String invalidTokens; 1262 m_policy ->enforceSandboxFlags(SecurityContext::parseSandboxPolicy(sandboxPolicy, invalidTokens));1225 m_policy.enforceSandboxFlags(SecurityContext::parseSandboxPolicy(sandboxPolicy, invalidTokens)); 1263 1226 if (!invalidTokens.isNull()) 1264 m_policy ->reportInvalidSandboxFlags(invalidTokens);1227 m_policy.reportInvalidSandboxFlags(invalidTokens); 1265 1228 } 1266 1229 … … 1268 1231 { 1269 1232 if (m_reflectedXSSDisposition != ContentSecurityPolicy::ReflectedXSSUnset) { 1270 m_policy ->reportDuplicateDirective(name);1233 m_policy.reportDuplicateDirective(name); 1271 1234 m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid; 1272 1235 return; … … 1275 1238 if (value.isEmpty()) { 1276 1239 m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid; 1277 m_policy ->reportInvalidReflectedXSS(value);1240 m_policy.reportInvalidReflectedXSS(value); 1278 1241 return; 1279 1242 } … … 1297 1260 else { 1298 1261 m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid; 1299 m_policy ->reportInvalidReflectedXSS(value);1262 m_policy.reportInvalidReflectedXSS(value); 1300 1263 return; 1301 1264 } … … 1308 1271 // ^ 1309 1272 m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid; 1310 m_policy ->reportInvalidReflectedXSS(value);1273 m_policy.reportInvalidReflectedXSS(value); 1311 1274 } 1312 1275 … … 1338 1301 parseReportURI(name, value); 1339 1302 #if ENABLE(CSP_NEXT) 1340 else if (m_policy ->experimentalFeaturesEnabled()) {1303 else if (m_policy.experimentalFeaturesEnabled()) { 1341 1304 if (equalLettersIgnoringASCIICase(name, baseURI)) 1342 1305 setCSPDirective<SourceListDirective>(name, value, m_baseURI); … … 1348 1311 parseReflectedXSS(name, value); 1349 1312 else 1350 m_policy ->reportUnsupportedDirective(name);1313 m_policy.reportUnsupportedDirective(name); 1351 1314 } 1352 1315 #endif 1353 1316 else 1354 m_policy->reportUnsupportedDirective(name); 1355 } 1356 1357 ContentSecurityPolicy::ContentSecurityPolicy(ScriptExecutionContext* scriptExecutionContext) 1358 : m_scriptExecutionContext(scriptExecutionContext) 1359 , m_overrideInlineStyleAllowed(false) 1360 { 1317 m_policy.reportUnsupportedDirective(name); 1318 } 1319 1320 ContentSecurityPolicy::ContentSecurityPolicy(ScriptExecutionContext& scriptExecutionContext) 1321 : m_scriptExecutionContext(&scriptExecutionContext) 1322 , m_sandboxFlags(SandboxNone) 1323 { 1324 ASSERT(scriptExecutionContext.securityOrigin()); 1325 auto& securityOrigin = *scriptExecutionContext.securityOrigin(); 1326 m_selfSourceProtocol = securityOrigin.protocol(); 1327 m_selfSource = std::make_unique<CSPSource>(*this, m_selfSourceProtocol, securityOrigin.host(), securityOrigin.port(), emptyString(), false, false); 1328 } 1329 1330 ContentSecurityPolicy::ContentSecurityPolicy(const SecurityOrigin& securityOrigin) 1331 : m_sandboxFlags(SandboxNone) 1332 { 1333 m_selfSourceProtocol = securityOrigin.protocol(); 1334 m_selfSource = std::make_unique<CSPSource>(*this, m_selfSourceProtocol, securityOrigin.host(), securityOrigin.port(), emptyString(), false, false); 1361 1335 } 1362 1336 … … 1401 1375 // header1,header2 OR header1 1402 1376 // ^ ^ 1403 std::unique_ptr<CSPDirectiveList> policy = CSPDirectiveList::create( this, String(begin, position - begin), type);1377 std::unique_ptr<CSPDirectiveList> policy = CSPDirectiveList::create(*this, String(begin, position - begin), type); 1404 1378 if (!policy->allowEval(0, ContentSecurityPolicy::ReportingStatus::SuppressReport)) 1405 m_ scriptExecutionContext->disableEval(policy->evalDisabledErrorMessage());1379 m_lastPolicyEvalDisabledErrorMessage = policy->evalDisabledErrorMessage(); 1406 1380 1407 1381 m_policies.append(policy.release()); … … 1412 1386 begin = position; 1413 1387 } 1388 1389 if (m_scriptExecutionContext) 1390 applyPolicyToScriptExecutionContext(); 1391 } 1392 1393 void ContentSecurityPolicy::applyPolicyToScriptExecutionContext() 1394 { 1395 ASSERT(m_scriptExecutionContext); 1396 if (!m_lastPolicyEvalDisabledErrorMessage.isNull()) 1397 m_scriptExecutionContext->disableEval(m_lastPolicyEvalDisabledErrorMessage); 1398 if (m_sandboxFlags != SandboxNone && is<Document>(m_scriptExecutionContext)) 1399 m_scriptExecutionContext->enforceSandboxFlags(m_sandboxFlags); 1414 1400 } 1415 1401 … … 1417 1403 { 1418 1404 m_overrideInlineStyleAllowed = value; 1405 } 1406 1407 bool ContentSecurityPolicy::urlMatchesSelf(const URL& url) const 1408 { 1409 return m_selfSource->matches(url); 1410 } 1411 1412 bool ContentSecurityPolicy::protocolMatchesSelf(const URL& url) const 1413 { 1414 #if ENABLE(CSP_NEXT) 1415 if (equalLettersIgnoringASCIICase(m_selfSourceProtocol, "http")) 1416 return url.protocolIsInHTTPFamily(); 1417 #endif 1418 return equalIgnoringASCIICase(url.protocol(), m_selfSourceProtocol); 1419 1419 } 1420 1420 … … 1574 1574 void ContentSecurityPolicy::gatherReportURIs(DOMStringList& list) const 1575 1575 { 1576 for (auto& policy : m_policies) 1577 policy->gatherReportURIs(list); 1578 } 1579 1580 SecurityOrigin* ContentSecurityPolicy::securityOrigin() const 1581 { 1582 return m_scriptExecutionContext->securityOrigin(); 1583 } 1584 1585 const URL& ContentSecurityPolicy::url() const 1586 { 1587 return m_scriptExecutionContext->url(); 1588 } 1589 1590 URL ContentSecurityPolicy::completeURL(const String& url) const 1591 { 1592 return m_scriptExecutionContext->completeURL(url); 1593 } 1594 1595 void ContentSecurityPolicy::enforceSandboxFlags(SandboxFlags mask) const 1596 { 1597 m_scriptExecutionContext->enforceSandboxFlags(mask); 1576 ASSERT(m_scriptExecutionContext); 1577 for (auto& policy : m_policies) { 1578 for (auto& url : policy->reportURIs()) 1579 list.append(m_scriptExecutionContext->completeURL(url).string()); 1580 } 1598 1581 } 1599 1582 … … 1629 1612 #endif 1630 1613 1631 void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL, const Vector< URL>& reportURIs, const String& header, const String& contextURL, const WTF::OrdinalNumber& contextLine, JSC::ExecState* state) const1614 void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL, const Vector<String>& reportURIs, const String& header, const String& contextURL, const WTF::OrdinalNumber& contextLine, JSC::ExecState* state) const 1632 1615 { 1633 1616 logToConsole(consoleMessage, contextURL, contextLine, state); 1634 1617 1635 1618 // FIXME: Support sending reports from worker. 1636 if (!is<Document>( *m_scriptExecutionContext))1619 if (!is<Document>(m_scriptExecutionContext)) 1637 1620 return; 1638 1621 … … 1691 1674 1692 1675 for (const auto& url : reportURIs) 1693 PingLoader::sendViolationReport(*frame, url, report.copyRef());1676 PingLoader::sendViolationReport(*frame, document.completeURL(url), report.copyRef()); 1694 1677 } 1695 1678 … … 1775 1758 { 1776 1759 // FIXME: <http://webkit.org/b/114317> ContentSecurityPolicy::logToConsole should include a column number 1777 m_scriptExecutionContext->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message, contextURL, contextLine.oneBasedInt(), 0, state); 1760 if (m_scriptExecutionContext) 1761 m_scriptExecutionContext->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message, contextURL, contextLine.oneBasedInt(), 0, state); 1778 1762 } 1779 1763 1780 1764 void ContentSecurityPolicy::reportBlockedScriptExecutionToInspector(const String& directiveText) const 1781 1765 { 1782 InspectorInstrumentation::scriptExecutionBlockedByCSP(m_scriptExecutionContext, directiveText); 1766 if (m_scriptExecutionContext) 1767 InspectorInstrumentation::scriptExecutionBlockedByCSP(m_scriptExecutionContext, directiveText); 1783 1768 } 1784 1769 -
trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h
r195948 r196012 1 1 /* 2 2 * Copyright (C) 2011 Google, Inc. All rights reserved. 3 * Copyright (C) 2016 Apple Inc. All rights reserved. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 28 29 29 30 #include "ContentSecurityPolicyResponseHeaders.h" 30 #include "URL.h"31 31 #include "ScriptState.h" 32 #include <memory>33 #include <wtf/RefCounted.h>34 32 #include <wtf/Vector.h> 35 33 #include <wtf/text/TextPosition.h> 36 #include <wtf/text/WTFString.h>37 34 38 35 namespace WTF { … … 43 40 44 41 class CSPDirectiveList; 42 class CSPSource; 45 43 class DOMStringList; 46 44 class ScriptExecutionContext; 47 45 class SecurityOrigin; 46 class URL; 48 47 48 typedef Vector<std::unique_ptr<CSPDirectiveList>> CSPDirectiveListVector; 49 49 typedef int SandboxFlags; 50 typedef Vector<std::unique_ptr<CSPDirectiveList>> CSPDirectiveListVector;51 50 52 51 class ContentSecurityPolicy { 53 52 WTF_MAKE_FAST_ALLOCATED; 54 53 public: 55 explicit ContentSecurityPolicy(ScriptExecutionContext*); 54 explicit ContentSecurityPolicy(ScriptExecutionContext&); 55 explicit ContentSecurityPolicy(const SecurityOrigin&); 56 56 ~ContentSecurityPolicy(); 57 57 58 58 void copyStateFrom(const ContentSecurityPolicy*); 59 60 enum class ReportingStatus {61 SendReport,62 SuppressReport63 };64 59 65 60 // Be sure to update the behavior of XSSAuditor::combineXSSProtectionHeaderAndCSP whenever you change this enum's content or ordering. … … 71 66 BlockReflectedXSS 72 67 }; 68 ReflectedXSSDisposition reflectedXSSDisposition() const; 73 69 74 70 ContentSecurityPolicyResponseHeaders responseHeaders() const; … … 76 72 void didReceiveHeader(const String&, ContentSecurityPolicyHeaderType); 77 73 74 enum class ReportingStatus { 75 SendReport, 76 SuppressReport 77 }; 78 78 bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const; 79 79 bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const; … … 82 82 bool allowEval(JSC::ExecState* = nullptr, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const; 83 83 bool allowPluginType(const String& type, const String& typeAttribute, const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const; 84 85 84 bool allowScriptFromSource(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const; 86 85 bool allowObjectFromSource(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const; … … 94 93 bool allowBaseURI(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const; 95 94 96 ReflectedXSSDisposition reflectedXSSDisposition() const;97 98 95 void setOverrideAllowInlineStyle(bool); 99 96 100 97 bool isActive() const; 98 101 99 void gatherReportURIs(DOMStringList&) const; 102 100 101 String evalDisabledErrorMessage() const; 102 103 bool experimentalFeaturesEnabled() const; 104 105 static bool shouldBypassMainWorldContentSecurityPolicy(ScriptExecutionContext&); 106 107 // The following functions are used by internal data structures to call back into this object when parsing, validating, 108 // and applying a Content Security Policy. 109 // FIXME: We should make the various directives serve only as state stores for the parsed policy and remove these functions. 110 // This class should traverse the directives, validating the policy, and applying it to the script execution context. 111 112 // Used by MediaListDirective 113 void reportInvalidPluginTypes(const String&) const; 114 115 // Used by CSPSourceList 103 116 void reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression) const; 117 void reportInvalidPathCharacter(const String& directiveName, const String& value, const char) const; 118 void reportInvalidSourceExpression(const String& directiveName, const String& source) const; 119 bool urlMatchesSelf(const URL&) const; 120 121 // Used by CSPDirectiveList 104 122 void reportDuplicateDirective(const String&) const; 105 123 void reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const; 106 void reportInvalidPathCharacter(const String& directiveName, const String& value, const char) const;107 void reportInvalidPluginTypes(const String&) const;108 124 void reportInvalidSandboxFlags(const String&) const; 109 void reportInvalidSourceExpression(const String& directiveName, const String& source) const;110 125 void reportInvalidReflectedXSS(const String&) const; 111 126 void reportMissingReportURI(const String&) const; 112 127 void reportUnsupportedDirective(const String&) const; 113 void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL, const Vector<URL>& reportURIs, const String& header, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const; 128 void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL, const Vector<String>& reportURIs, const String& header, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const; 129 void reportBlockedScriptExecutionToInspector(const String& directiveText) const; 130 void enforceSandboxFlags(SandboxFlags sandboxFlags) { m_sandboxFlags |= sandboxFlags; } 114 131 115 void reportBlockedScriptExecutionToInspector(const String& directiveText) const; 116 117 const URL& url() const; 118 URL completeURL(const String&) const; 119 SecurityOrigin* securityOrigin() const; 120 void enforceSandboxFlags(SandboxFlags) const; 121 String evalDisabledErrorMessage() const; 122 123 bool experimentalFeaturesEnabled() const; 124 static bool shouldBypassMainWorldContentSecurityPolicy(ScriptExecutionContext&); 132 // Used by CSPSource 133 bool protocolMatchesSelf(const URL&) const; 125 134 126 135 private: 127 136 void logToConsole(const String& message, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const; 137 void applyPolicyToScriptExecutionContext(); 128 138 129 ScriptExecutionContext* m_scriptExecutionContext; 130 bool m_overrideInlineStyleAllowed; 139 ScriptExecutionContext* m_scriptExecutionContext { nullptr }; 140 std::unique_ptr<CSPSource> m_selfSource; 141 String m_selfSourceProtocol; 131 142 CSPDirectiveListVector m_policies; 143 String m_lastPolicyEvalDisabledErrorMessage; 144 SandboxFlags m_sandboxFlags; 145 bool m_overrideInlineStyleAllowed { false }; 132 146 }; 133 147 -
trunk/Source/WebCore/workers/WorkerGlobalScope.cpp
r195948 r196012 73 73 { 74 74 setSecurityOriginPolicy(SecurityOriginPolicy::create(SecurityOrigin::create(url))); 75 setContentSecurityPolicy(std::make_unique<ContentSecurityPolicy>(*this)); 75 76 } 76 77 … … 88 89 void WorkerGlobalScope::applyContentSecurityPolicyResponseHeaders(const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders) 89 90 { 90 setContentSecurityPolicy(std::make_unique<ContentSecurityPolicy>(this));91 91 contentSecurityPolicy()->didReceiveHeaders(contentSecurityPolicyResponseHeaders); 92 92 }
Note: See TracChangeset
for help on using the changeset viewer.