WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch and Layout Test
bug-155007-20160304124556.patch (text/plain), 93.65 KB, created by
Daniel Bates
on 2016-03-04 12:46:10 PST
(
hide
)
Description:
Patch and Layout Test
Filename:
MIME Type:
Creator:
Daniel Bates
Created:
2016-03-04 12:46:10 PST
Size:
93.65 KB
patch
obsolete
>Subversion Revision: 197580 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 511f7d988d0a8090b2b170999decec26784627f2..4dfe6a0237552e84fe132e7ed52f83bc42a1dc13 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,95 @@ >+2016-03-04 Daniel Bates <dabates@apple.com> >+ >+ CSP: Implement support for inline script and inline style hashes >+ https://bugs.webkit.org/show_bug.cgi?id=155007 >+ <rdar://problem/24964098> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Inspiration taken from the analogous implementation in Blink. >+ >+ Add support for script-src and style-src hashes as per sections Hash usage for script elements >+ and Hash usage for style elements of the Content Security Policy 2.0 spec., <https://www.w3.org/TR/2015/CR-CSP2-20150721/>. >+ >+ Test: http/tests/security/contentSecurityPolicy/1.1/scripthash-tests.html >+ >+ * WebCore.xcodeproj/project.pbxproj: Add file ContentSecurityPolicyHash.h. Also sort the list of files >+ in the group WebCore/page/csp. >+ * dom/InlineStyleSheetOwner.cpp: >+ (WebCore::InlineStyleSheetOwner::createSheet): Pass the content of the stylesheet when querying whether >+ the stylesheet is allowed by the Content Security Policy. >+ * dom/ScriptElement.cpp: >+ (WebCore::ScriptElement::executeScript): Pass the content of the inline JavaScript script when querying >+ whether the script is allowed by the Content Security Policy. >+ * dom/StyledElement.cpp: >+ (WebCore::StyledElement::styleAttributeChanged): The Content Security Policy style-src hashes do not apply >+ to inline styles defined in the HTML style attribute. So, pass a null string (to indicate the absence of >+ content) when querying whether the inline style is allowed by the Content Security Policy. >+ * page/csp/ContentSecurityPolicy.cpp: >+ (WebCore::toCryptoDigestAlgorithm): Convenience function that maps a ContentSecurityPolicyHashAlgorithm >+ enumerator to a CryptoDigest::Algorithm enumerator. >+ (WebCore::isAllowedByAllWithHashFromContent): Computes the digest of the specified content for each >+ hash algorithm and checks if digest matches a hash that was specified in a policy. >+ (WebCore::ContentSecurityPolicy::documentEncoding): Added. >+ (WebCore::ContentSecurityPolicy::allowInlineScript): Check if the hash of the script matches a known >+ hash if applicable. Otherwise, fall back to checking the URL of the script. >+ (WebCore::ContentSecurityPolicy::allowInlineStyle): Check if the hash of the stylesheet matches a >+ known hash if applicable. Otherwise, fall back to checking the URL of the stylesheet. >+ * page/csp/ContentSecurityPolicy.h: >+ (WebCore::ContentSecurityPolicy::addHashAlgorithmsForInlineScripts): Adds the specified set of >+ hash algorithms to the existing set of hash algorithms we know are used for inline scripts. >+ (WebCore::ContentSecurityPolicy::addHashAlgorithmsForInlineStylesheets): Adds the specified set of >+ hash algorithms to the existing set of hash algorithms we know are used for inline stylesheets. >+ * page/csp/ContentSecurityPolicyDirectiveList.cpp: >+ (WebCore::checkEval): Make this a static, non-member function because it does not depend on any >+ instance or class variables. Mark this function as inline to give a hint to the compiler that it >+ should consider inlining the implementation of this function into the caller. >+ (WebCore::checkInline): Ditto. >+ (WebCore::checkSource): Ditto. >+ (WebCore::checkHash): Checks if the directive allows content with the specified hash. >+ (WebCore::checkMediaType): Make this a static, non-member function because it does not depend on >+ any instance or class variables. Mark this function as inline to give a hint to the compiler that >+ it should consider inlining the implementation of this function into the caller. >+ (WebCore::ContentSecurityPolicyDirectiveList::create): Modified as needed now that WebCore::checkEval() >+ is a static, non-member function. >+ (WebCore::ContentSecurityPolicyDirectiveList::allowInlineScriptWithHash): Added. >+ (WebCore::ContentSecurityPolicyDirectiveList::allowInlineStyleWithHash): Added. >+ (WebCore::ContentSecurityPolicyDirectiveList::addDirective): Modified to pass the hash algorithms seen >+ from parsing the directives script-src, style-src, and default-src to the ContentSecurityPolicy object. >+ (WebCore::ContentSecurityPolicyDirectiveList::checkEval): Deleted. >+ (WebCore::ContentSecurityPolicyDirectiveList::checkInline): Deleted. >+ (WebCore::ContentSecurityPolicyDirectiveList::checkSource): Deleted. >+ (WebCore::ContentSecurityPolicyDirectiveList::checkMediaType): Deleted. >+ * page/csp/ContentSecurityPolicyDirectiveList.h: >+ * page/csp/ContentSecurityPolicyHash.h: Added. >+ (WTF::DefaultHash<WebCore::ContentSecurityPolicyDigest>::Hash::hash): Compute the hash of a digest as >+ we would compute the hash of a string. >+ (WTF::DefaultHash<WebCore::ContentSecurityPolicyDigest>::Hash::equal): Compare the digests for equality >+ by making use Vector's equality operator. >+ * page/csp/ContentSecurityPolicySourceList.cpp: >+ (WebCore::ContentSecurityPolicySourceList::matches): Checks if the hash is in the set of known hashes. >+ (WebCore::ContentSecurityPolicySourceList::parse): Modified to call ContentSecurityPolicySourceList::parseHashSource() >+ to try to parse the source list expression as a hash source. If this fails then we try to parse the >+ source expression as a scheme/host/port expression. >+ (WebCore::parseHashAlgorithmAdvancingPosition): Parses the hash algorithm from a hash source expression. >+ (WebCore::isBase64Character): Returns whether the specified character is a valid Base64/Base64url character, >+ excluding the padding character '='. Disregarding the omission of the padding character '=', this function >+ conforms to the ABNF grammar defined in section Source Lists of the Content Security Policy Level 3 spec., >+ <https://w3c.github.io/webappsec-csp> (Editorâs Draft, 29 February 2016). We take the padding character '=' >+ into account in ContentSecurityPolicySourceList::parseHashSource(). >+ (WebCore::ContentSecurityPolicySourceList::parseHashSource): Parses a hash source expression per the ABNF >+ grammar described in section Source Lists of the Content Security Policy Level 3 spec. >+ * page/csp/ContentSecurityPolicySourceList.h: >+ (WebCore::ContentSecurityPolicySourceList::hashAlgorithmsUsed): Returns the set of hash algorithms seen from >+ parsing the source list. >+ (WebCore::ContentSecurityPolicySourceList::allowInline): We only allow inline scripts/stylesheets if >+ 'unsafe-inline' was specified in the source list and the source list does not contain any hash sources. >+ * page/csp/ContentSecurityPolicySourceListDirective.cpp: >+ (WebCore::ContentSecurityPolicySourceListDirective::allows): Checks if the specified hash is in the source list. >+ * page/csp/ContentSecurityPolicySourceListDirective.h: >+ (WebCore::ContentSecurityPolicySourceListDirective::hashAlgorithmsUsed): Turns around and calls ContentSecurityPolicySourceList::hashAlgorithmsUsed(). >+ >+ > 2016-03-04 Simon Fraser <simon.fraser@apple.com> > > Fix crash seen in iOS simulator tests >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index d43efebf0a703a2f5b68ef91890f348b94f768c9..76403d5ec472ca3f448fee7707b4fb173c8806c6 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -6214,6 +6214,7 @@ > CE7B2DB41586ABAD0098B3FA /* AlternativeTextUIController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CE7B2DB01586ABAD0098B3FA /* AlternativeTextUIController.mm */; }; > CE7B2DB51586ABAD0098B3FA /* TextAlternativeWithRange.h in Headers */ = {isa = PBXBuildFile; fileRef = CE7B2DB11586ABAD0098B3FA /* TextAlternativeWithRange.h */; settings = {ATTRIBUTES = (Private, ); }; }; > CE7B2DB61586ABAD0098B3FA /* TextAlternativeWithRange.mm in Sources */ = {isa = PBXBuildFile; fileRef = CE7B2DB21586ABAD0098B3FA /* TextAlternativeWithRange.mm */; }; >+ CE7E17831C83A49100AD06AF /* ContentSecurityPolicyHash.h in Headers */ = {isa = PBXBuildFile; fileRef = CE7E17821C83A49100AD06AF /* ContentSecurityPolicyHash.h */; }; > CE95208A1811B475007A5392 /* WebSafeIncrementalSweeperIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C4CB1D161A131200D214DA /* WebSafeIncrementalSweeperIOS.h */; }; > CEC337AD1A46071F009B8523 /* ServersSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CEC337AC1A46071F009B8523 /* ServersSPI.h */; settings = {ATTRIBUTES = (Private, ); }; }; > CEC337AF1A46086D009B8523 /* GraphicsServicesSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CEC337AE1A46086D009B8523 /* GraphicsServicesSPI.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -14210,6 +14211,7 @@ > CE7B2DB01586ABAD0098B3FA /* AlternativeTextUIController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AlternativeTextUIController.mm; sourceTree = "<group>"; }; > CE7B2DB11586ABAD0098B3FA /* TextAlternativeWithRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextAlternativeWithRange.h; sourceTree = "<group>"; }; > CE7B2DB21586ABAD0098B3FA /* TextAlternativeWithRange.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TextAlternativeWithRange.mm; sourceTree = "<group>"; }; >+ CE7E17821C83A49100AD06AF /* ContentSecurityPolicyHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ContentSecurityPolicyHash.h; path = csp/ContentSecurityPolicyHash.h; sourceTree = "<group>"; }; > CEC337AC1A46071F009B8523 /* ServersSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServersSPI.h; sourceTree = "<group>"; }; > CEC337AE1A46086D009B8523 /* GraphicsServicesSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphicsServicesSPI.h; sourceTree = "<group>"; }; > CECADFC2153778FF00E37068 /* DictationAlternative.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DictationAlternative.cpp; sourceTree = "<group>"; }; >@@ -23137,6 +23139,7 @@ > CE799FA21C6A503A0097B518 /* ContentSecurityPolicyDirective.h */, > CE799F991C6A4BCD0097B518 /* ContentSecurityPolicyDirectiveList.cpp */, > CE799F9A1C6A4BCD0097B518 /* ContentSecurityPolicyDirectiveList.h */, >+ CE7E17821C83A49100AD06AF /* ContentSecurityPolicyHash.h */, > CE799FA51C6A50570097B518 /* ContentSecurityPolicyMediaListDirective.cpp */, > CE799FA61C6A50570097B518 /* ContentSecurityPolicyMediaListDirective.h */, > CE6DADF71C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.cpp */, >@@ -25230,6 +25233,7 @@ > 97C471DC12F925BD0086354B /* ContentSecurityPolicy.h in Headers */, > CE799FA41C6A503A0097B518 /* ContentSecurityPolicyDirective.h in Headers */, > CE799F9C1C6A4BCD0097B518 /* ContentSecurityPolicyDirectiveList.h in Headers */, >+ CE7E17831C83A49100AD06AF /* ContentSecurityPolicyHash.h in Headers */, > CE799FA81C6A50570097B518 /* ContentSecurityPolicyMediaListDirective.h in Headers */, > CE6DADFA1C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.h in Headers */, > CE799FA01C6A4C160097B518 /* ContentSecurityPolicySource.h in Headers */, >diff --git a/Source/WebCore/dom/InlineStyleSheetOwner.cpp b/Source/WebCore/dom/InlineStyleSheetOwner.cpp >index e6e7acdb00a014fb7958d76c5283be09170365f1..14faedb894109aecdd8fc32c4c14276a313238d4 100644 >--- a/Source/WebCore/dom/InlineStyleSheetOwner.cpp >+++ b/Source/WebCore/dom/InlineStyleSheetOwner.cpp >@@ -135,7 +135,7 @@ void InlineStyleSheetOwner::createSheet(Element& element, const String& text) > > if (!isValidCSSContentType(element, m_contentType)) > return; >- if (!document.contentSecurityPolicy()->allowInlineStyle(document.url(), m_startTextPosition.m_line, element.isInUserAgentShadowTree())) >+ if (!document.contentSecurityPolicy()->allowInlineStyle(document.url(), m_startTextPosition.m_line, text, element.isInUserAgentShadowTree())) > return; > > RefPtr<MediaQuerySet> mediaQueries; >diff --git a/Source/WebCore/dom/ScriptElement.cpp b/Source/WebCore/dom/ScriptElement.cpp >index 521028195ab2981dda099f904039432a408819a0..303cb07cf06297512a061341974a54f039609803 100644 >--- a/Source/WebCore/dom/ScriptElement.cpp >+++ b/Source/WebCore/dom/ScriptElement.cpp >@@ -293,7 +293,7 @@ void ScriptElement::executeScript(const ScriptSourceCode& sourceCode) > if (sourceCode.isEmpty()) > return; > >- if (!m_isExternalScript && !m_element.document().contentSecurityPolicy()->allowInlineScript(m_element.document().url(), m_startLineNumber, m_element.isInUserAgentShadowTree())) >+ if (!m_isExternalScript && !m_element.document().contentSecurityPolicy()->allowInlineScript(m_element.document().url(), m_startLineNumber, sourceCode.source().toStringWithoutCopying(), m_element.isInUserAgentShadowTree())) > return; > > #if ENABLE(NOSNIFF) >diff --git a/Source/WebCore/dom/StyledElement.cpp b/Source/WebCore/dom/StyledElement.cpp >index e5d06633d046bf261f82009a5f8cab90d8975078..e7c328a440154ed47ded1bf9b788a7bbde405632 100644 >--- a/Source/WebCore/dom/StyledElement.cpp >+++ b/Source/WebCore/dom/StyledElement.cpp >@@ -202,7 +202,7 @@ void StyledElement::styleAttributeChanged(const AtomicString& newStyleString, At > if (PropertySetCSSStyleDeclaration* cssomWrapper = inlineStyleCSSOMWrapper()) > cssomWrapper->clearParentElement(); > ensureUniqueElementData().m_inlineStyle = nullptr; >- } else if (reason == ModifiedByCloning || document().contentSecurityPolicy()->allowInlineStyle(document().url(), startLineNumber, isInUserAgentShadowTree())) >+ } else if (reason == ModifiedByCloning || document().contentSecurityPolicy()->allowInlineStyle(document().url(), startLineNumber, String(), isInUserAgentShadowTree())) > setInlineStyleFromString(newStyleString); > > elementData()->setStyleAttributeIsDirty(false); >diff --git a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp >index 9ff1574079979d8760866db050f648d19889e046..bde0c2d2c83b44cf927c7c77e5c94ab206acdb8b 100644 >--- a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp >+++ b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp >@@ -29,8 +29,10 @@ > > #include "ContentSecurityPolicyDirective.h" > #include "ContentSecurityPolicyDirectiveList.h" >+#include "ContentSecurityPolicyHash.h" > #include "ContentSecurityPolicySource.h" > #include "ContentSecurityPolicySourceList.h" >+#include "CryptoDigest.h" > #include "DOMStringList.h" > #include "Document.h" > #include "DocumentLoader.h" >@@ -45,6 +47,7 @@ > #include "SchemeRegistry.h" > #include "SecurityOrigin.h" > #include "SecurityPolicyViolationEvent.h" >+#include "TextEncoding.h" > #include <inspector/InspectorValues.h> > #include <inspector/ScriptCallStack.h> > #include <inspector/ScriptCallStackFactory.h> >@@ -183,6 +186,37 @@ bool isAllowedByAllWithContext(const CSPDirectiveListVector& policies, const Str > return true; > } > >+static CryptoDigest::Algorithm toCryptoDigestAlgorithm(ContentSecurityPolicyHashAlgorithm algorithm) >+{ >+ switch (algorithm) { >+ case ContentSecurityPolicyHashAlgorithm::SHA_256: >+ return CryptoDigest::Algorithm::SHA_256; >+ case ContentSecurityPolicyHashAlgorithm::SHA_384: >+ return CryptoDigest::Algorithm::SHA_384; >+ case ContentSecurityPolicyHashAlgorithm::SHA_512: >+ return CryptoDigest::Algorithm::SHA_512; >+ } >+ ASSERT_NOT_REACHED(); >+ return CryptoDigest::Algorithm::SHA_512; >+} >+ >+template<bool (ContentSecurityPolicyDirectiveList::*allowed)(const ContentSecurityPolicyHash&) const> >+bool isAllowedByAllWithHashFromContent(const CSPDirectiveListVector& policies, const String& content, const TextEncoding& encoding, OptionSet<ContentSecurityPolicyHashAlgorithm> algorithms) >+{ >+ // FIXME: Compute the digest with respect to the raw bytes received from the page. >+ CString contentCString = encoding.encode(content, EntitiesForUnencodables); >+ for (auto algorithm : algorithms) { >+ auto cryptoDigest = CryptoDigest::create(toCryptoDigestAlgorithm(algorithm)); >+ cryptoDigest->addBytes(contentCString.data(), contentCString.length()); >+ Vector<uint8_t> digest = cryptoDigest->computeHash(); >+ for (auto& policy : policies) { >+ if ((policy.get()->*allowed)(std::make_pair(algorithm, digest))) >+ return true; >+ } >+ } >+ return false; >+} >+ > template<bool (ContentSecurityPolicyDirectiveList::*allowFromURL)(const URL&, ContentSecurityPolicy::ReportingStatus) const> > bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) > { >@@ -206,14 +240,37 @@ bool ContentSecurityPolicy::allowInlineEventHandlers(const String& contextURL, c > return overrideContentSecurityPolicy || isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowInlineEventHandlers>(m_policies, contextURL, contextLine, reportingStatus); > } > >-bool ContentSecurityPolicy::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const >+// FIXME: We should compute the document encoding once and cache it instead of computing it on each invocation. >+const TextEncoding& ContentSecurityPolicy::documentEncoding() const >+{ >+ if (!is<Document>(m_scriptExecutionContext)) >+ return UTF8Encoding(); >+ Document& document = downcast<Document>(*m_scriptExecutionContext); >+ if (TextResourceDecoder* decoder = document.decoder()) >+ return decoder->encoding(); >+ return UTF8Encoding(); >+} >+ >+bool ContentSecurityPolicy::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, const String& scriptContent, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const > { >- return overrideContentSecurityPolicy || isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowInlineScript>(m_policies, contextURL, contextLine, reportingStatus); >+ if (overrideContentSecurityPolicy) >+ return true; >+ if (!m_hashAlgorithmsForInlineScripts.isEmpty() && !scriptContent.isEmpty() >+ && isAllowedByAllWithHashFromContent<&ContentSecurityPolicyDirectiveList::allowInlineScriptWithHash>(m_policies, scriptContent, documentEncoding(), m_hashAlgorithmsForInlineScripts)) >+ return true; >+ return isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowInlineScript>(m_policies, contextURL, contextLine, reportingStatus); > } > >-bool ContentSecurityPolicy::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const >+bool ContentSecurityPolicy::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, const String& styleContent, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const > { >- return overrideContentSecurityPolicy || m_overrideInlineStyleAllowed || isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowInlineStyle>(m_policies, contextURL, contextLine, reportingStatus); >+ if (overrideContentSecurityPolicy) >+ return true; >+ if (m_overrideInlineStyleAllowed) >+ return true; >+ if (!m_hashAlgorithmsForInlineStylesheets.isEmpty() && !styleContent.isEmpty() >+ && isAllowedByAllWithHashFromContent<&ContentSecurityPolicyDirectiveList::allowInlineStyleWithHash>(m_policies, styleContent, documentEncoding(), m_hashAlgorithmsForInlineStylesheets)) >+ return true; >+ return isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowInlineStyle>(m_policies, contextURL, contextLine, reportingStatus); > } > > bool ContentSecurityPolicy::allowEval(JSC::ExecState* state, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const >diff --git a/Source/WebCore/page/csp/ContentSecurityPolicy.h b/Source/WebCore/page/csp/ContentSecurityPolicy.h >index bc0c5899cd4efbbcc69f55d081229066ad98692a..4b959e16eb688e9180c9b1954c4bb8947686d2a9 100644 >--- a/Source/WebCore/page/csp/ContentSecurityPolicy.h >+++ b/Source/WebCore/page/csp/ContentSecurityPolicy.h >@@ -29,6 +29,7 @@ > > #include "ContentSecurityPolicyResponseHeaders.h" > #include "ScriptState.h" >+#include <wtf/OptionSet.h> > #include <wtf/Vector.h> > #include <wtf/text/TextPosition.h> > >@@ -43,8 +44,11 @@ class ContentSecurityPolicySource; > class DOMStringList; > class ScriptExecutionContext; > class SecurityOrigin; >+class TextEncoding; > class URL; > >+enum class ContentSecurityPolicyHashAlgorithm; >+ > typedef Vector<std::unique_ptr<ContentSecurityPolicyDirectiveList>> CSPDirectiveListVector; > typedef int SandboxFlags; > >@@ -82,8 +86,8 @@ public: > }; > bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const; > bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const; >- bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const; >- bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const; >+ bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, const String& scriptContent, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const; >+ bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, const String& styleContent, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const; > bool allowEval(JSC::ExecState* = nullptr, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const; > bool allowPluginType(const String& type, const String& typeAttribute, const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const; > bool allowScriptFromSource(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const; >@@ -134,6 +138,14 @@ public: > 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; > void reportBlockedScriptExecutionToInspector(const String& directiveText) const; > void enforceSandboxFlags(SandboxFlags sandboxFlags) { m_sandboxFlags |= sandboxFlags; } >+ void addHashAlgorithmsForInlineScripts(OptionSet<ContentSecurityPolicyHashAlgorithm> hashAlgorithmsForInlineScripts) >+ { >+ m_hashAlgorithmsForInlineScripts |= hashAlgorithmsForInlineScripts; >+ } >+ void addHashAlgorithmsForInlineStylesheets(OptionSet<ContentSecurityPolicyHashAlgorithm> hashAlgorithmsForInlineStylesheets) >+ { >+ m_hashAlgorithmsForInlineStylesheets |= hashAlgorithmsForInlineStylesheets; >+ } > > // Used by ContentSecurityPolicySource > bool protocolMatchesSelf(const URL&) const; >@@ -144,6 +156,8 @@ private: > > void didReceiveHeader(const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicy::PolicyFrom); > >+ const TextEncoding& documentEncoding() const; >+ > ScriptExecutionContext* m_scriptExecutionContext { nullptr }; > std::unique_ptr<ContentSecurityPolicySource> m_selfSource; > String m_selfSourceProtocol; >@@ -151,6 +165,8 @@ private: > String m_lastPolicyEvalDisabledErrorMessage; > SandboxFlags m_sandboxFlags; > bool m_overrideInlineStyleAllowed { false }; >+ OptionSet<ContentSecurityPolicyHashAlgorithm> m_hashAlgorithmsForInlineScripts; >+ OptionSet<ContentSecurityPolicyHashAlgorithm> m_hashAlgorithmsForInlineStylesheets; > }; > > } >diff --git a/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp b/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp >index 01cfa51343d8109eb92f9e3e0d24129fa9afbcfc..2ac09d842f7a78ca6452f2292209ea5317ecc840 100644 >--- a/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp >+++ b/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp >@@ -105,6 +105,35 @@ static bool isNotASCIISpace(UChar c) > return !isASCIISpace(c); > } > >+static inline bool checkEval(ContentSecurityPolicySourceListDirective* directive) >+{ >+ return !directive || directive->allowEval(); >+} >+ >+static inline bool checkInline(ContentSecurityPolicySourceListDirective* directive) >+{ >+ return !directive || directive->allowInline(); >+} >+ >+static inline bool checkSource(ContentSecurityPolicySourceListDirective* directive, const URL& url) >+{ >+ return !directive || directive->allows(url); >+} >+ >+static inline bool checkHash(ContentSecurityPolicySourceListDirective* directive, const ContentSecurityPolicyHash& hash) >+{ >+ return !directive || directive->allows(hash); >+} >+ >+static inline bool checkMediaType(ContentSecurityPolicyMediaListDirective* directive, const String& type, const String& typeAttribute) >+{ >+ if (!directive) >+ return true; >+ if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type) >+ return false; >+ return directive->allows(type); >+} >+ > ContentSecurityPolicyDirectiveList::ContentSecurityPolicyDirectiveList(ContentSecurityPolicy& policy, ContentSecurityPolicyHeaderType type) > : m_policy(policy) > , m_headerType(type) >@@ -120,7 +149,7 @@ std::unique_ptr<ContentSecurityPolicyDirectiveList> ContentSecurityPolicyDirecti > auto directives = std::make_unique<ContentSecurityPolicyDirectiveList>(policy, type); > directives->parse(header, from); > >- if (!directives->checkEval(directives->operativeDirective(directives->m_scriptSrc.get()))) { >+ if (!checkEval(directives->operativeDirective(directives->m_scriptSrc.get()))) { > String message = makeString("Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: \"", directives->operativeDirective(directives->m_scriptSrc.get())->text(), "\".\n"); > directives->setEvalDisabledErrorMessage(message); > } >@@ -137,30 +166,6 @@ void ContentSecurityPolicyDirectiveList::reportViolation(const String& directive > m_policy.reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header, contextURL, contextLine, state); > } > >-bool ContentSecurityPolicyDirectiveList::checkEval(ContentSecurityPolicySourceListDirective* directive) const >-{ >- return !directive || directive->allowEval(); >-} >- >-bool ContentSecurityPolicyDirectiveList::checkInline(ContentSecurityPolicySourceListDirective* directive) const >-{ >- return !directive || directive->allowInline(); >-} >- >-bool ContentSecurityPolicyDirectiveList::checkSource(ContentSecurityPolicySourceListDirective* directive, const URL& url) const >-{ >- return !directive || directive->allows(url); >-} >- >-bool ContentSecurityPolicyDirectiveList::checkMediaType(ContentSecurityPolicyMediaListDirective* directive, const String& type, const String& typeAttribute) const >-{ >- if (!directive) >- return true; >- if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type) >- return false; >- return directive->allows(type); >-} >- > ContentSecurityPolicySourceListDirective* ContentSecurityPolicyDirectiveList::operativeDirective(ContentSecurityPolicySourceListDirective* directive) const > { > return directive ? directive : m_defaultSrc.get(); >@@ -278,6 +283,11 @@ bool ContentSecurityPolicyDirectiveList::allowInlineScript(const String& context > return m_reportOnly || checkInline(operativeDirective(m_scriptSrc.get())); > } > >+bool ContentSecurityPolicyDirectiveList::allowInlineScriptWithHash(const ContentSecurityPolicyHash& hash) const >+{ >+ return checkHash(operativeDirective(m_scriptSrc.get()), hash); >+} >+ > bool ContentSecurityPolicyDirectiveList::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const > { > static NeverDestroyed<String> consoleMessage(ASCIILiteral("Refused to apply inline style because it violates the following Content Security Policy directive: ")); >@@ -286,6 +296,11 @@ bool ContentSecurityPolicyDirectiveList::allowInlineStyle(const String& contextU > return m_reportOnly || checkInline(operativeDirective(m_styleSrc.get())); > } > >+bool ContentSecurityPolicyDirectiveList::allowInlineStyleWithHash(const ContentSecurityPolicyHash& hash) const >+{ >+ return checkHash(operativeDirective(m_styleSrc.get()), hash); >+} >+ > bool ContentSecurityPolicyDirectiveList::allowEval(JSC::ExecState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const > { > static NeverDestroyed<String> consoleMessage(ASCIILiteral("Refused to evaluate script because it violates the following Content Security Policy directive: ")); >@@ -579,18 +594,22 @@ void ContentSecurityPolicyDirectiveList::addDirective(const String& name, const > { > ASSERT(!name.isEmpty()); > >- if (equalLettersIgnoringASCIICase(name, defaultSrc)) >+ if (equalLettersIgnoringASCIICase(name, defaultSrc)) { > setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_defaultSrc); >- else if (equalLettersIgnoringASCIICase(name, scriptSrc)) >+ m_policy.addHashAlgorithmsForInlineScripts(m_defaultSrc->hashAlgorithmsUsed()); >+ m_policy.addHashAlgorithmsForInlineStylesheets(m_defaultSrc->hashAlgorithmsUsed()); >+ } else if (equalLettersIgnoringASCIICase(name, scriptSrc)) { > setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_scriptSrc); >- else if (equalLettersIgnoringASCIICase(name, objectSrc)) >+ m_policy.addHashAlgorithmsForInlineScripts(m_scriptSrc->hashAlgorithmsUsed()); >+ } else if (equalLettersIgnoringASCIICase(name, styleSrc)) { >+ setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_styleSrc); >+ m_policy.addHashAlgorithmsForInlineStylesheets(m_styleSrc->hashAlgorithmsUsed()); >+ } else if (equalLettersIgnoringASCIICase(name, objectSrc)) > setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_objectSrc); > else if (equalLettersIgnoringASCIICase(name, frameSrc)) > setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_frameSrc); > else if (equalLettersIgnoringASCIICase(name, imgSrc)) > setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_imgSrc); >- else if (equalLettersIgnoringASCIICase(name, styleSrc)) >- setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_styleSrc); > else if (equalLettersIgnoringASCIICase(name, fontSrc)) > setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_fontSrc); > else if (equalLettersIgnoringASCIICase(name, mediaSrc)) >diff --git a/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h b/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h >index 2a98b2d0994941f5b305a24e527cbfd34ab24461..3f658fd8513547811e95fb7593320c097d810c23 100644 >--- a/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h >+++ b/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h >@@ -28,6 +28,7 @@ > #define ContentSecurityPolicyDirectiveList_h > > #include "ContentSecurityPolicy.h" >+#include "ContentSecurityPolicyHash.h" > #include "ContentSecurityPolicyMediaListDirective.h" > #include "ContentSecurityPolicySourceListDirective.h" > #include "URL.h" >@@ -50,7 +51,9 @@ public: > bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const; > bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const; > bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const; >+ bool allowInlineScriptWithHash(const ContentSecurityPolicyHash&) const; > bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const; >+ bool allowInlineStyleWithHash(const ContentSecurityPolicyHash&) const; > bool allowEval(JSC::ExecState*, ContentSecurityPolicy::ReportingStatus) const; > bool allowPluginType(const String& type, const String& typeAttribute, const URL&, ContentSecurityPolicy::ReportingStatus) const; > >@@ -87,11 +90,6 @@ private: > ContentSecurityPolicySourceListDirective* operativeDirective(ContentSecurityPolicySourceListDirective*) const; > void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL = URL(), const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const; > >- bool checkEval(ContentSecurityPolicySourceListDirective*) const; >- bool checkInline(ContentSecurityPolicySourceListDirective*) const; >- bool checkSource(ContentSecurityPolicySourceListDirective*, const URL&) const; >- bool checkMediaType(ContentSecurityPolicyMediaListDirective*, const String& type, const String& typeAttribute) const; >- > void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisabledErrorMessage = errorMessage; } > > bool checkEvalAndReportViolation(ContentSecurityPolicySourceListDirective*, const String& consoleMessage, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const; >diff --git a/Source/WebCore/page/csp/ContentSecurityPolicyHash.h b/Source/WebCore/page/csp/ContentSecurityPolicyHash.h >new file mode 100644 >index 0000000000000000000000000000000000000000..12a94f261b0ee6b30020b722884461313fefd599 >--- /dev/null >+++ b/Source/WebCore/page/csp/ContentSecurityPolicyHash.h >@@ -0,0 +1,69 @@ >+/* >+ * Copyright (C) 2016 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef ContentSecurityPolicyHash_h >+#define ContentSecurityPolicyHash_h >+ >+#include <wtf/HashTraits.h> >+#include <wtf/Hasher.h> >+#include <wtf/Vector.h> >+ >+namespace WebCore { >+ >+// Keep this synchronized with the constant maximumContentSecurityPolicyDigestLength below. >+enum class ContentSecurityPolicyHashAlgorithm { >+ SHA_256 = 1 << 0, >+ SHA_384 = 1 << 1, >+ SHA_512 = 1 << 2, >+}; >+ >+const size_t maximumContentSecurityPolicyDigestLength = 64; // bytes to hold SHA-512 digest >+ >+typedef Vector<uint8_t> ContentSecurityPolicyDigest; >+typedef std::pair<ContentSecurityPolicyHashAlgorithm, ContentSecurityPolicyDigest> ContentSecurityPolicyHash; >+ >+} >+ >+namespace WTF { >+ >+template<> struct DefaultHash<WebCore::ContentSecurityPolicyHashAlgorithm> { typedef IntHash<WebCore::ContentSecurityPolicyHashAlgorithm> Hash; }; >+template<> struct HashTraits<WebCore::ContentSecurityPolicyHashAlgorithm> : StrongEnumHashTraits<WebCore::ContentSecurityPolicyHashAlgorithm> { }; >+template<> struct DefaultHash<WebCore::ContentSecurityPolicyDigest> { >+ struct Hash { >+ static unsigned hash(const WebCore::ContentSecurityPolicyDigest& digest) >+ { >+ return StringHasher::computeHashAndMaskTop8Bits(digest.data(), digest.size()); >+ } >+ static bool equal(const WebCore::ContentSecurityPolicyDigest& a, const WebCore::ContentSecurityPolicyDigest& b) >+ { >+ return a == b; >+ } >+ static const bool safeToCompareToEmptyOrDeleted = true; >+ }; >+}; >+ >+} >+ >+#endif // ContentSecurityPolicyHash_h >diff --git a/Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp b/Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp >index f3dac7bd59fcc15b8590d3534c6796537f55b42e..d9da9b593c8b7b0466156302945832c92b12bca8 100644 >--- a/Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp >+++ b/Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp >@@ -33,6 +33,7 @@ > #include "SecurityOrigin.h" > #include "URL.h" > #include <wtf/ASCIICType.h> >+#include <wtf/text/Base64.h> > > namespace WebCore { > >@@ -114,6 +115,11 @@ bool ContentSecurityPolicySourceList::matches(const URL& url) > return false; > } > >+bool ContentSecurityPolicySourceList::matches(const ContentSecurityPolicyHash& hash) const >+{ >+ return m_hashes.contains(hash); >+} >+ > // source-list = *WSP [ source *( 1*WSP source ) *WSP ] > // / *WSP "'none'" *WSP > // >@@ -134,6 +140,9 @@ void ContentSecurityPolicySourceList::parse(const UChar* begin, const UChar* end > bool hostHasWildcard = false; > bool portHasWildcard = false; > >+ if (parseHashSource(beginSource, position)) >+ continue; >+ > if (parseSource(beginSource, position, scheme, host, port, path, hostHasWildcard, portHasWildcard)) { > // Wildcard hosts and keyword sources ('self', 'unsafe-inline', > // etc.) aren't stored in m_list, but as attributes on the source >@@ -374,4 +383,71 @@ bool ContentSecurityPolicySourceList::parsePort(const UChar* begin, const UChar* > return ok; > } > >+static bool parseHashAlgorithmAdvancingPosition(const UChar*& position, size_t length, ContentSecurityPolicyHashAlgorithm& algorithm) >+{ >+ static const struct { >+ const char* label; >+ ContentSecurityPolicyHashAlgorithm algorithm; >+ } labelToHashAlgorithmTable[] { >+ { "sha256", ContentSecurityPolicyHashAlgorithm::SHA_256 }, >+ { "sha384", ContentSecurityPolicyHashAlgorithm::SHA_384 }, >+ { "sha512", ContentSecurityPolicyHashAlgorithm::SHA_512 }, >+ }; >+ >+ for (auto& entry : labelToHashAlgorithmTable) { >+ size_t labelLength = strlen(entry.label); >+ if (length < labelLength || !equalLettersIgnoringASCIICase(position, entry.label, labelLength)) >+ continue; >+ position += labelLength; >+ algorithm = entry.algorithm; >+ return true; // Found >+ } >+ return false; // Not found >+} >+ >+static bool isBase64Character(UChar c) >+{ >+ return isASCIIAlphanumeric(c) || c == '+' || c == '/' || c == '-' || c == '_'; >+} >+ >+// hash-source = "'" hash-algorithm "-" base64-value "'" >+// hash-algorithm = "sha256" / "sha384" / "sha512" >+// base64-value = 1*( ALPHA / DIGIT / "+" / "/" / "-" / "_" )*2( "=" ) >+bool ContentSecurityPolicySourceList::parseHashSource(const UChar* begin, const UChar* end) >+{ >+ if (begin == end) >+ return false; >+ >+ const UChar* position = begin; >+ if (!skipExactly<UChar>(position, end, '\'')) >+ return false; >+ >+ ContentSecurityPolicyHashAlgorithm algorithm; >+ if (!parseHashAlgorithmAdvancingPosition(position, end - position, algorithm)) >+ return false; >+ >+ if (!skipExactly<UChar>(position, end, '-')) >+ return false; >+ >+ const UChar* beginHashValue = position; >+ skipWhile<UChar, isBase64Character>(position, end); >+ skipExactly<UChar>(position, end, '='); >+ skipExactly<UChar>(position, end, '='); >+ if (position >= end || position == beginHashValue || *position != '\'') >+ return false; >+ Vector<uint8_t> digest; >+ StringView hashValue(beginHashValue, position - beginHashValue); // base64url or base64 encoded >+ // FIXME: Normalize Base64URL to Base64 instead of decoding twice. >+ if (!base64Decode(hashValue.toStringWithoutCopying(), digest, Base64ValidatePadding)) { >+ if (!base64URLDecode(hashValue.toStringWithoutCopying(), digest)) >+ return false; >+ } >+ if (digest.size() > maximumContentSecurityPolicyDigestLength) >+ return false; >+ >+ m_hashes.add(std::make_pair(algorithm, digest)); >+ m_hashAlgorithmsUsed |= algorithm; >+ return true; >+} >+ > } // namespace WebCore >diff --git a/Source/WebCore/page/csp/ContentSecurityPolicySourceList.h b/Source/WebCore/page/csp/ContentSecurityPolicySourceList.h >index 0646a9f5978a452a8c3a959d7fb505ca373e7b08..3b8c3c66d31f566ee6f1891fcd67eb0b651ba628 100644 >--- a/Source/WebCore/page/csp/ContentSecurityPolicySourceList.h >+++ b/Source/WebCore/page/csp/ContentSecurityPolicySourceList.h >@@ -27,8 +27,10 @@ > #ifndef ContentSecurityPolicySourceList_h > #define ContentSecurityPolicySourceList_h > >+#include "ContentSecurityPolicyHash.h" > #include "ContentSecurityPolicySource.h" >-#include <wtf/Vector.h> >+#include <wtf/HashSet.h> >+#include <wtf/OptionSet.h> > #include <wtf/text/WTFString.h> > > namespace WebCore { >@@ -41,8 +43,13 @@ public: > ContentSecurityPolicySourceList(const ContentSecurityPolicy&, const String& directiveName); > > void parse(const String&); >+ > bool matches(const URL&); >- bool allowInline() const { return m_allowInline; } >+ bool matches(const ContentSecurityPolicyHash&) const; >+ >+ OptionSet<ContentSecurityPolicyHashAlgorithm> hashAlgorithmsUsed() const { return m_hashAlgorithmsUsed; } >+ >+ bool allowInline() const { return m_allowInline && m_hashes.isEmpty(); } > bool allowEval() const { return m_allowEval; } > bool allowSelf() const { return m_allowSelf; } > >@@ -55,8 +62,12 @@ private: > bool parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard); > bool parsePath(const UChar* begin, const UChar* end, String& path); > >+ bool parseHashSource(const UChar* begin, const UChar* end); >+ > const ContentSecurityPolicy& m_policy; > Vector<ContentSecurityPolicySource> m_list; >+ HashSet<ContentSecurityPolicyHash> m_hashes; >+ OptionSet<ContentSecurityPolicyHashAlgorithm> m_hashAlgorithmsUsed; > String m_directiveName; > bool m_allowSelf { false }; > bool m_allowStar { false }; >diff --git a/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.cpp b/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.cpp >index 89133d4ebb51c0443e4990ce1c608064e4b1b256..a167f850ff4ffdad83077ed8120bcf3aa8fd7872 100644 >--- a/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.cpp >+++ b/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.cpp >@@ -47,4 +47,9 @@ bool ContentSecurityPolicySourceListDirective::allows(const URL& url) > return m_sourceList.matches(url); > } > >+bool ContentSecurityPolicySourceListDirective::allows(const ContentSecurityPolicyHash& hash) const >+{ >+ return m_sourceList.matches(hash); >+} >+ > } // namespace WebCore >diff --git a/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.h b/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.h >index 9d4e2114c9ec39224cd408e2ad2a6423f68e648c..c890903ef2fb9977b0c346acae40610ef179a225 100644 >--- a/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.h >+++ b/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.h >@@ -39,9 +39,12 @@ public: > ContentSecurityPolicySourceListDirective(const String& name, const String& value, const ContentSecurityPolicy&); > > bool allows(const URL&); >+ bool allows(const ContentSecurityPolicyHash&) const; > bool allowInline() const { return m_sourceList.allowInline(); } > bool allowEval() const { return m_sourceList.allowEval(); } > >+ OptionSet<ContentSecurityPolicyHashAlgorithm> hashAlgorithmsUsed() const { return m_sourceList.hashAlgorithmsUsed(); } >+ > private: > ContentSecurityPolicySourceList m_sourceList; > }; >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 537f620ef23e7de8bcdd903d0e40e6d20db4881e..2103167b6ff91a2465981da7e869c1be904fc085 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,42 @@ >+2016-03-04 Daniel Bates <dabates@apple.com> >+ >+ CSP: Implement support for inline script and inline style hashes >+ https://bugs.webkit.org/show_bug.cgi?id=155007 >+ <rdar://problem/24964098> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add new test http/tests/security/contentSecurityPolicy/1.1/scripthash-tests.html to ensure that >+ script hashes are interpreted correctly. Update many existing tests that had a hash source with >+ SHA-1 hash to use a SHA-256 hash. The valid hash algorithms SHA-256, SHA-384, and SHA-512 >+ per the Content Security Policy Level 3 spec. At the time of writing, Blink also supports SHA-1. >+ >+ * TestExpectations: Mark many CSP 1.1 tests as PASS so that we run them. Remove entries for tests >+ http/tests/security/contentSecurityPolicy/1.1/{script, style}hash-default-src.html as these tests >+ now pass. >+ * http/tests/security/contentSecurityPolicy/1.1/resources/didRunInlineScriptEpilogue.js: Added. >+ * http/tests/security/contentSecurityPolicy/1.1/resources/didRunInlineScriptPrologue.js: Added. >+ * http/tests/security/contentSecurityPolicy/1.1/resources/testScriptHash.php: Added. >+ * http/tests/security/contentSecurityPolicy/1.1/scripthash-allowed.html: Update test as SHA-1 is not >+ a supported hash algorithm per the Content Security Policy Level 3 spec. >+ * http/tests/security/contentSecurityPolicy/1.1/scripthash-basic-blocked-expected.txt: Ditto. >+ * http/tests/security/contentSecurityPolicy/1.1/scripthash-basic-blocked.html: Ditto. >+ * http/tests/security/contentSecurityPolicy/1.1/scripthash-ignore-unsafeinline-expected.txt: Ditto. >+ * http/tests/security/contentSecurityPolicy/1.1/scripthash-ignore-unsafeinline.html: Ditto. >+ * http/tests/security/contentSecurityPolicy/1.1/scripthash-malformed-expected.txt: >+ * http/tests/security/contentSecurityPolicy/1.1/scripthash-tests-expected.txt: Added. >+ * http/tests/security/contentSecurityPolicy/1.1/scripthash-tests.html: Added. >+ * http/tests/security/contentSecurityPolicy/1.1/scripthash-unicode-normalization.html: Update test >+ as SHA-1 is not a supported hash algorithm per the Content Security Policy Level 3 spec. >+ * http/tests/security/contentSecurityPolicy/1.1/stylehash-allowed-expected.txt: Ditto. >+ * http/tests/security/contentSecurityPolicy/1.1/stylehash-allowed.html: Ditto. >+ * http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked-error-event.html: Ditto. >+ * http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked-expected.txt: Ditto. >+ * http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked.html: Ditto. >+ * http/tests/security/contentSecurityPolicy/1.1/stylehash-default-src-expected.txt: Added. >+ * http/tests/security/contentSecurityPolicy/1.1/stylehash-svg-style-basic-blocked-error-event.html: Update test >+ as SHA-1 is not a supported hash algorithm per the Content Security Policy Level 3 spec. >+ > 2016-03-04 Chris Dumez <cdumez@apple.com> > > Location.reload should not be writable >diff --git a/LayoutTests/TestExpectations b/LayoutTests/TestExpectations >index 64ce329c590dd3013504df6bcafb182969f42922..5e24ecf65c484385fb2d546da6e48703ced4a512 100644 >--- a/LayoutTests/TestExpectations >+++ b/LayoutTests/TestExpectations >@@ -816,15 +816,21 @@ http/tests/security/contentSecurityPolicy/1.1/base-uri-allow.html [ Pass ] > http/tests/security/contentSecurityPolicy/1.1/base-uri-default-ignored.html [ Pass ] > http/tests/security/contentSecurityPolicy/1.1/base-uri-deny.html [ Pass ] > http/tests/security/contentSecurityPolicy/1.1/report-uri-effective-directive.php [ Pass ] >+http/tests/security/contentSecurityPolicy/1.1/scripthash-allowed.html [ Pass ] >+http/tests/security/contentSecurityPolicy/1.1/scripthash-basic-blocked.html [ Pass ] >+http/tests/security/contentSecurityPolicy/1.1/scripthash-default-src.html [ Pass ] >+http/tests/security/contentSecurityPolicy/1.1/scripthash-ignore-unsafeinline.html [ Pass ] >+http/tests/security/contentSecurityPolicy/1.1/scripthash-malformed.html [ Pass ] >+http/tests/security/contentSecurityPolicy/1.1/scripthash-tests.html [ Pass ] >+http/tests/security/contentSecurityPolicy/1.1/scripthash-unicode-normalization.html [ Pass ] > http/tests/security/contentSecurityPolicy/1.1/securitypolicyviolation-basics.html [ Pass ] > http/tests/security/contentSecurityPolicy/1.1/securitypolicyviolation-block-cross-origin-image-from-script.html [ Pass ] > http/tests/security/contentSecurityPolicy/1.1/securitypolicyviolation-block-cross-origin-image.html [ Pass ] > http/tests/security/contentSecurityPolicy/1.1/securitypolicyviolation-block-image-from-script.html [ Pass ] > http/tests/security/contentSecurityPolicy/1.1/securitypolicyviolation-block-image-https.html [ Pass ] > http/tests/security/contentSecurityPolicy/1.1/securitypolicyviolation-block-image.html [ Pass ] >-webkit.org/b/154203 http/tests/security/contentSecurityPolicy/1.1/frame-ancestors/frame-ancestors-overrides-xfo.html >-webkit.org/b/154203 http/tests/security/contentSecurityPolicy/1.1/scripthash-default-src.html >-webkit.org/b/154203 http/tests/security/contentSecurityPolicy/1.1/stylehash-default-src.html >+http/tests/security/contentSecurityPolicy/1.1/stylehash-allowed.html [ Pass ] >+http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked.html [ Pass ] > http/tests/security/contentSecurityPolicy/1.1/plugintypes-affects-child.html [ Pass ] > http/tests/security/contentSecurityPolicy/1.1/plugintypes-invalid.html [ Pass ] > http/tests/security/contentSecurityPolicy/1.1/plugintypes-mismatched-data.html [ Pass ] >@@ -835,6 +841,7 @@ http/tests/security/contentSecurityPolicy/1.1/plugintypes-nourl-allowed.html [ P > http/tests/security/contentSecurityPolicy/1.1/plugintypes-nourl-blocked.html [ Pass ] > http/tests/security/contentSecurityPolicy/1.1/plugintypes-url-01.html [ Pass ] > http/tests/security/contentSecurityPolicy/1.1/plugintypes-url-02.html [ Pass ] >+webkit.org/b/154203 http/tests/security/contentSecurityPolicy/1.1/frame-ancestors/frame-ancestors-overrides-xfo.html > webkit.org/b/111869 http/tests/security/contentSecurityPolicy/eval-blocked-and-sends-report.html > webkit.org/b/115700 http/tests/security/contentSecurityPolicy/inline-event-handler-blocked-after-injecting-meta.html [ Failure ] > webkit.org/b/153148 http/tests/security/contentSecurityPolicy/eval-allowed-in-report-only-mode-and-sends-report.html >@@ -851,6 +858,9 @@ webkit.org/b/153153 http/tests/security/contentSecurityPolicy/object-src-param-s > webkit.org/b/153153 http/tests/security/contentSecurityPolicy/object-src-param-url-blocked.html > webkit.org/b/153154 http/tests/security/contentSecurityPolicy/redirect-does-not-match-paths.html > webkit.org/b/153155 http/tests/security/contentSecurityPolicy/style-src-blocked-error-event.html >+webkit.org/b/153155 http/tests/security/contentSecurityPolicy/1.1/scripthash-basic-blocked-error-event.html >+webkit.org/b/153155 http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked-error-event.html >+webkit.org/b/153155 http/tests/security/contentSecurityPolicy/1.1/stylehash-svg-style-basic-blocked-error-event.html > webkit.org/b/153159 http/tests/security/contentSecurityPolicy/image-document-default-src-none.html [ Failure ] > webkit.org/b/153160 http/tests/security/contentSecurityPolicy/object-src-does-not-affect-child.html [ Failure ] > webkit.org/b/153160 http/tests/security/contentSecurityPolicy/plugin-in-iframe-with-csp.html [ Failure ] >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/resources/didRunInlineScriptEpilogue.js b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/resources/didRunInlineScriptEpilogue.js >new file mode 100644 >index 0000000000000000000000000000000000000000..a741405932df13b9b1abefd4d96b66ea0bb3942f >--- /dev/null >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/resources/didRunInlineScriptEpilogue.js >@@ -0,0 +1 @@ >+window.parent.checkResult(didRunInlineScript); >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/resources/didRunInlineScriptPrologue.js b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/resources/didRunInlineScriptPrologue.js >new file mode 100644 >index 0000000000000000000000000000000000000000..f5b8bb9576fdb702dc426f5499c97405afe08169 >--- /dev/null >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/resources/didRunInlineScriptPrologue.js >@@ -0,0 +1 @@ >+var didRunInlineScript = false; >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/resources/testScriptHash.php b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/resources/testScriptHash.php >new file mode 100644 >index 0000000000000000000000000000000000000000..4de0cf0f1cc8ebd0c055e353e9f019c2dae6cdfd >--- /dev/null >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/resources/testScriptHash.php >@@ -0,0 +1,15 @@ >+<?php >+ header("Expires: Thu, 01 Dec 2003 16:00:00 GMT"); >+ header("Cache-Control: no-cache, must-revalidate"); >+ header("Pragma: no-cache"); >+ header("Content-Type: text/html; charset=" . (empty($_GET["charset"]) ? "UTF8" : $_GET["charset"])); >+ header("Content-Security-Policy: script-src 'self' " . $_GET["hashSource"]); >+?> >+<!DOCTYPE html> >+<html> >+<head> >+<script src="didRunInlineScriptPrologue.js"></script> >+<script><?php echo $_GET["script"]; ?></script> <!-- Will only execute if $_GET["hashSource"] represents a valid hash of this script. --> >+<script src="didRunInlineScriptEpilogue.js"></script> >+</head> >+</html> >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-allowed.html b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-allowed.html >index 65e8f9a0218be35eabe30ac5547abe790d68629d..01bba332f80280a69fe7130e353cc4fc29bed404 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-allowed.html >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-allowed.html >@@ -1,12 +1,12 @@ > <!DOCTYPE html> > <html> > <head> >- <meta http-equiv="Content-Security-Policy" content="script-src 'sha1-vMUNaexq6wlYKxWWPlJUOvhn67U=' 'sha256-j+ToFnhur5mTSCwoyy4Fh29+1BNMVEZ0MBvG5db0dA4=' 'sha384-S/1WrU/8y14JzSAhjkxjd8sZLP10LDlHuH8Mi24OwMNJ6wSry7J8ln0KeaibHHBW' 'sha512-0tQJUSPHRGUYQIa2ByQWZSlUa5sI3e2tOEXF7sg5mjmsHk/EHDTTORIDyMPhDKgCmdYdb7TIrwhLrq2kEvfjHQ=='"> > <script> > if (window.testRunner) > testRunner.dumpAsText(); > alert('PASS (1/4)'); > </script> >+ <meta http-equiv="Content-Security-Policy" content="script-src 'sha256-j+ToFnhur5mTSCwoyy4Fh29+1BNMVEZ0MBvG5db0dA4=' 'sha384-S/1WrU/8y14JzSAhjkxjd8sZLP10LDlHuH8Mi24OwMNJ6wSry7J8ln0KeaibHHBW' 'sha512-0tQJUSPHRGUYQIa2ByQWZSlUa5sI3e2tOEXF7sg5mjmsHk/EHDTTORIDyMPhDKgCmdYdb7TIrwhLrq2kEvfjHQ=='"> > <script> > alert('PASS (2/4)'); > </script> >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-basic-blocked-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-basic-blocked-expected.txt >index f0a15ad1e0e8f33b82e5bf00b88b00ab42f3b5ed..7a968596b1f6f660db2bf18e6b3439a05ab40218 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-basic-blocked-expected.txt >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-basic-blocked-expected.txt >@@ -1,10 +1,10 @@ > ALERT: PASS (1/1) >-CONSOLE MESSAGE: line 10: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'sha1-Au4uYFbkf7OYd+ACMnKq96FN3qo='". Either the 'unsafe-inline' keyword, a hash ('sha256-bXMksCHhVxMyxdbJpZuZicpO8HCDLuN9ZzcfnlVeN4k='), or a nonce ('nonce-...') is required to enable inline execution. >+CONSOLE MESSAGE: line 10: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'sha256-0WwzeJrO6lcDUe7o6BR3lx0b8uiBvXBX5MNFFKF7iYE'". > >-CONSOLE MESSAGE: line 13: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'sha1-Au4uYFbkf7OYd+ACMnKq96FN3qo='". Either the 'unsafe-inline' keyword, a hash ('sha256-WJxPiOlT6TFxc+Ol71ivP0eHtjokcBKNXLU0usIYZz4='), or a nonce ('nonce-...') is required to enable inline execution. >+CONSOLE MESSAGE: line 13: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'sha256-0WwzeJrO6lcDUe7o6BR3lx0b8uiBvXBX5MNFFKF7iYE'". > >-CONSOLE MESSAGE: line 15: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'sha1-Au4uYFbkf7OYd+ACMnKq96FN3qo='". Either the 'unsafe-inline' keyword, a hash ('sha256-IytoJzJfZC0NOAbaSFNz+QyLVnbrELCXScgDL6ldIwE='), or a nonce ('nonce-...') is required to enable inline execution. >+CONSOLE MESSAGE: line 15: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'sha256-0WwzeJrO6lcDUe7o6BR3lx0b8uiBvXBX5MNFFKF7iYE'". > >-CONSOLE MESSAGE: line 16: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'sha1-Au4uYFbkf7OYd+ACMnKq96FN3qo='". Either the 'unsafe-inline' keyword, a hash ('sha256-GK8kAPOt6ZIhmzOr3QzHpIkbTXB/Jpc6PXuliF2zoj0='), or a nonce ('nonce-...') is required to enable inline execution. >+CONSOLE MESSAGE: line 16: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'sha256-0WwzeJrO6lcDUe7o6BR3lx0b8uiBvXBX5MNFFKF7iYE'". > > This tests the effect of a valid script-hash value, with one valid script and several invalid ones. It passes if one alert is executed and four console warings are visible. >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-basic-blocked.html b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-basic-blocked.html >index 48667866cfbd796dcac1b308cabfc81920385875..0d559a9da9fe2ad4e1dfa6d26d7439a139bab473 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-basic-blocked.html >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-basic-blocked.html >@@ -1,7 +1,7 @@ > <!DOCTYPE html> > <html> > <head> >- <meta http-equiv="Content-Security-Policy" content="script-src 'sha1-Au4uYFbkf7OYd+ACMnKq96FN3qo='"> >+ <meta http-equiv="Content-Security-Policy" content="script-src 'sha256-0WwzeJrO6lcDUe7o6BR3lx0b8uiBvXBX5MNFFKF7iYE'"> > <script> > if (window.testRunner) > testRunner.dumpAsText(); >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-ignore-unsafeinline-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-ignore-unsafeinline-expected.txt >index 6f43f416d309c29f4075b820c81baf9a8c18bdec..af3d302d66584501709345d0d1c57db038753063 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-ignore-unsafeinline-expected.txt >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-ignore-unsafeinline-expected.txt >@@ -1,4 +1,4 @@ > ALERT: PASS (1/1) >-CONSOLE MESSAGE: line 10: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'sha1-Au4uYFbkf7OYd+ACMnKq96FN3qo=' 'unsafe-inline'". Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list. >+CONSOLE MESSAGE: line 10: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'sha256-0WwzeJrO6lcDUe7o6BR3lx0b8uiBvXBX5MNFFKF7iYE' 'unsafe-inline'". > > This tests that a valid hash value disables inline JavaScript, even if 'unsafe-inline' is present. >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-ignore-unsafeinline.html b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-ignore-unsafeinline.html >index 709ba205b468056ec0b812fca514e4e1194c7ad0..01bdbc60b631f58dae4d012c921e4871d978ab23 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-ignore-unsafeinline.html >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-ignore-unsafeinline.html >@@ -1,7 +1,7 @@ > <!DOCTYPE html> > <html> > <head> >- <meta http-equiv="Content-Security-Policy" content="script-src 'sha1-Au4uYFbkf7OYd+ACMnKq96FN3qo=' 'unsafe-inline'"> >+ <meta http-equiv="Content-Security-Policy" content="script-src 'sha256-0WwzeJrO6lcDUe7o6BR3lx0b8uiBvXBX5MNFFKF7iYE' 'unsafe-inline'"> > <script> > if (window.testRunner) > testRunner.dumpAsText(); >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-malformed-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-malformed-expected.txt >index 7384e1f3b002e832c017272e030b223a5a4d9a77..b5981b9bb4cc7948ebfaa7489e6080df563b23dd 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-malformed-expected.txt >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-malformed-expected.txt >@@ -1,4 +1,5 @@ >-CONSOLE MESSAGE: line 5: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha256-j+ToFnhur5mTSCwoyy4Fh'. It will be ignored. >-CONSOLE MESSAGE: line 5: Unrecognized Content-Security-Policy directive ''sha512-0tQJUSPHRGUYQIa2ByQWZSlUa5sI3e2tOEXF7sg5mjmsHk/EHDTTORIDyMPhDKgCmb7TIrwhLrq2kEvfjHQ==''. >+CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha1-vMUNaexq6wlYKxWWPlJUOvhn67U=''. It will be ignored. >+CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha256-j+ToFnhur5mTSCwoyy4Fh'. It will be ignored. >+CONSOLE MESSAGE: Unrecognized Content-Security-Policy directive ''sha512-0tQJUSPHRGUYQIa2ByQWZSlUa5sI3e2tOEXF7sg5mjmsHk/EHDTTORIDyMPhDKgCmb7TIrwhLrq2kEvfjHQ==''. > > >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-tests-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-tests-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..4fe8dcfd18328f5efd98ab2da8498c85bf461ea4 >--- /dev/null >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-tests-expected.txt >@@ -0,0 +1,84 @@ >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'sha256-rrdh0QCl46qqHxfnnk08ydh/rkhVi2JvD6DLuUP30MI='". >+ >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'sha256-W4kKNfgvUMesHeVX1eGn6f3LfuntH7p4YjLeOauCA/I='". >+ >+CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA=''. It will be ignored. >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'sha-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA='". >+ >+CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha-dummy''. It will be ignored. >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'sha-dummy'". >+ >+CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''d&mmy''. It will be ignored. >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'd&mmy'". >+ >+CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA=''. It will be ignored. >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' '/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA='". >+ >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'sha384-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA='". >+ >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'sha512-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA='". >+ >+CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha256-/Vet2Rva6wwsny8xybL+=bQal0Gtf0FZW7EOVqqg+Hna=''. It will be ignored. >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'sha256-/Vet2Rva6wwsny8xybL+=bQal0Gtf0FZW7EOVqqg+Hna='". >+ >+CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha256-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA==''. It will be ignored. >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'sha256-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA=='". >+ >+CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha256-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA===''. It will be ignored. >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'sha256-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA==='". >+ >+CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha256-'. It will be ignored. >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'sha256-". >+ >+CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha256-''. It will be ignored. >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'sha256-'". >+ >+CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha256-#''. It will be ignored. >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'sha256-#'". >+ >+CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha256-abc&=''. It will be ignored. >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'sha256-abc&='". >+ >+CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha256-abc&==''. It will be ignored. >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'sha256-abc&=='". >+ >+CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha256-LyogVGhpcyBpcyBhIGxvbmcgY29tbWVudCB0aGF0IHdpbGwgYmUgZW5jb2RlZCB1c2luZyBCYXNlNjQgdG8gcHJvZHVjZSBhbiBlbmNvZGVkIHN0cmluZyBvdXRwdXQgdGhhdCBpcyBsb25nZXIgdGhhbiBhIFNlY3VyZSBIYXNoIEFsZ29yaXRobS01MTIgZGlnZXN0LiAqLw==''. It will be ignored. >+CONSOLE MESSAGE: line 5: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'sha256-LyogVGhpcyBpcyBhIGxvbmcgY29tbWVudCB0aGF0IHdpbGwgYmUgZW5jb2RlZCB1c2luZyBCYXNlNjQgdG8gcHJvZHVjZSBhbiBlbmNvZGVkIHN0cmluZyBvdXRwdXQgdGhhdCBpcyBsb25nZXIgdGhhbiBhIFNlY3VyZSBIYXNoIEFsZ29yaXRobS01MTIgZGlnZXN0LiAqLw=='". >+ >+This tests that script hashes work and conform to the Content Security Policy 2.0 specification. >+ >+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". >+ >+ >+PASS "Base64 encoded SHA-256 hash" did run inline script. >+PASS "Base64 encoded SHA-256 hash with mixed case prefix" did run inline script. >+PASS "Base64url encoded SHA-256 hash" did run inline script. >+PASS "Base64 encoded SHA-384 hash" did run inline script. >+PASS "Base64url encoded SHA-384 hash" did run inline script. >+PASS "Base64 encoded SHA-512 hash" did run inline script. >+PASS "Base64url encoded SHA-512 hash" did run inline script. >+PASS "Script that contains HTML entity >" did run inline script. >+PASS "Script that contains Unicode code point U+00C5" did run inline script. >+PASS "Unicode code point U+00C5 is not equivalent to U+212B" did not run inline script. >+PASS "Unicode code point U+212B is equivalent to U+00C5" did run inline script. >+PASS "Big-5 page with Big-5 hash" did run inline script. >+PASS "Big-5 page with UTF-8 hash" did not run inline script. >+PASS "Hash source with invalid prefix" did not run inline script. >+PASS "Invalid prefix" did not run inline script. >+PASS "Invalid hash and no prefix" did not run inline script. >+PASS "Hash without prefix" did not run inline script. >+PASS "SHA-256 hash with SHA-384 prefix" did not run inline script. >+PASS "SHA-256 hash with SHA-512 prefix" did not run inline script. >+PASS "Malformed SHA-256 hash (equal sign in disallowed position)" did not run inline script. >+PASS "SHA-256 hash with one extraneous equal sign" did not run inline script. >+PASS "SHA-256 hash with two extraneous equal signs" did not run inline script. >+PASS "Malformed hash source" did not run inline script. >+PASS "Hash source without hash" did not run inline script. >+PASS "Hash source without invalid hash" did not run inline script. >+PASS "Hash source without invalid hash2" did not run inline script. >+PASS "Hash source without invalid hash3" did not run inline script. >+PASS "Hash that is larger that 64 bytes" did not run inline script. >+PASS successfullyParsed is true >+ >+TEST COMPLETE >+ >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-tests.html b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-tests.html >new file mode 100644 >index 0000000000000000000000000000000000000000..cbae88dce10e48a207e26dcc7d1c918eab3933b9 >--- /dev/null >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-tests.html >@@ -0,0 +1,275 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<script src="/js-test-resources/js-test-pre.js"></script> >+<script> >+window.jsTestIsAsync = true; >+ >+const DoNotRunInlineScript = false; >+const RunInlineScript = true; >+ >+var tests = [ >+// Simple >+{ >+ name: "Base64 encoded SHA-256 hash", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha256-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA='", >+ expectedResult: RunInlineScript, >+}, >+{ >+ name: "Base64 encoded SHA-256 hash with mixed case prefix", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'SHa256-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA='", >+ expectedResult: RunInlineScript, >+}, >+{ >+ name: "Base64url encoded SHA-256 hash", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'SHa256-_vET2rVA6WWSNY8XYBl-BqAL0gTF0fzw7eovQQG-hNA='", >+ expectedResult: RunInlineScript, >+}, >+{ >+ name: "Base64 encoded SHA-384 hash", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha384-+2z3lkISbDOt4AKFTEPrIPQK77NC7dumupDVevpcOzg5bsdmKh0tI9t6kDLJzEqH'", >+ expectedResult: RunInlineScript, >+}, >+{ >+ name: "Base64url encoded SHA-384 hash", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha384--2z3lkISbDOt4AKFTEPrIPQK77NC7dumupDVevpcOzg5bsdmKh0tI9t6kDLJzEqH'", >+ expectedResult: RunInlineScript, >+}, >+{ >+ name: "Base64 encoded SHA-512 hash", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha512-Qh1vKVk9nyoM8LWzH9RkfEBQNxky/6izE0GbZ2D7RkwwuTQPC2pIG+ReFxOfnijVvqeopfYZShxvpLIGWdpRwg=='", >+ expectedResult: RunInlineScript, >+}, >+{ >+ name: "Base64url encoded SHA-512 hash", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha512-Qh1vKVk9nyoM8LWzH9RkfEBQNxky_6izE0GbZ2D7RkwwuTQPC2pIG-ReFxOfnijVvqeopfYZShxvpLIGWdpRwg=='", >+ expectedResult: RunInlineScript, >+}, >+// HTML entity test case >+{ >+ name: "Script that contains HTML entity >", >+ charset: "UTF8", >+ script: "didRunInlineScript+%3D+true%3B+//+%26gt%3B", >+ hashSource: "'sha256-Wcu0hRB2z5RQ2pcRLxzsVob2mmIuW0Qt+xRwr5n6hKM='", >+ expectedResult: RunInlineScript, >+}, >+// Unicode normalization test cases >+{ >+ name: "Script that contains Unicode code point U+00C5", >+ charset: "UTF8", >+ script: "didRunInlineScript+%3D+true%3B+//+%C3%85", // %C3%85 is the URL encoded UTF-8 byte sequence for U+00C5. >+ hashSource: "'sha256-K3oo3dJj28X47TIh/UinhDWS3C5DfcQVCRzw4JM7SWE='", >+ expectedResult: RunInlineScript, >+}, >+{ >+ name: "Unicode code point U+00C5 is not equivalent to U+212B", >+ charset: "UTF8", >+ script: "didRunInlineScript+%3D+true%3B+//+%C3%85", // %C3%85 is the URL encoded UTF-8 byte sequence for U+00C5. >+ hashSource: "'sha256-rrdh0QCl46qqHxfnnk08ydh/rkhVi2JvD6DLuUP30MI='", // Hash of "didRunInlineScript+%3D+true%3B+//+%E2%84%AB" >+ expectedResult: DoNotRunInlineScript, >+}, >+{ >+ name: "Unicode code point U+212B is equivalent to U+00C5", >+ charset: "UTF8", >+ script: "didRunInlineScript+%3D+true%3B+//+%E2%84%AB", // %E2%84%AB is the URL encoded UTF-8 byte sequence for U+212B. >+ hashSource: "'sha256-K3oo3dJj28X47TIh/UinhDWS3C5DfcQVCRzw4JM7SWE='", // Intentionally not 'sha256-rrdh0QCl46qqHxfnnk08ydh/rkhVi2JvD6DLuUP30MI=' >+ expectedResult: RunInlineScript, >+}, >+// Big-5 encoding test cases >+{ >+ name: "Big-5 page with Big-5 hash", >+ charset: "Big5", >+ script: "didRunInlineScript+%3D+true%3B+//+%A4%F4", >+ hashSource: "'sha256-J08nmORtZZyj86mnbklnHBObVEnsakqZcYsabqsSJmc='", >+ expectedResult: RunInlineScript, >+}, >+{ >+ name: "Big-5 page with UTF-8 hash", >+ charset: "Big5", >+ script: "didRunInlineScript+%3D+true%3B+//+%A4%F4", >+ hashSource: "'sha256-W4kKNfgvUMesHeVX1eGn6f3LfuntH7p4YjLeOauCA/I='", >+ expectedResult: DoNotRunInlineScript, >+}, >+// Malformed and invalid test cases >+{ >+ name: "Hash source with invalid prefix", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA='", >+ expectedResult: DoNotRunInlineScript, >+}, >+{ >+ name: "Invalid prefix", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha-dummy'", >+ expectedResult: DoNotRunInlineScript, >+}, >+{ >+ name: "Invalid hash and no prefix", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'d&mmy'", >+ expectedResult: DoNotRunInlineScript, >+}, >+{ >+ name: "Hash without prefix", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA='", >+ expectedResult: DoNotRunInlineScript, >+}, >+{ >+ name: "SHA-256 hash with SHA-384 prefix", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha384-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA='", >+ expectedResult: DoNotRunInlineScript, >+}, >+{ >+ name: "SHA-256 hash with SHA-512 prefix", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha512-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA='", >+ expectedResult: DoNotRunInlineScript, >+}, >+{ >+ name: "Malformed SHA-256 hash (equal sign in disallowed position)", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha256-/Vet2Rva6wwsny8xybL+=bQal0Gtf0FZW7EOVqqg+Hna='", >+ expectedResult: DoNotRunInlineScript, >+}, >+{ >+ name: "SHA-256 hash with one extraneous equal sign", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha256-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA=='", >+ expectedResult: DoNotRunInlineScript, >+}, >+{ >+ name: "SHA-256 hash with two extraneous equal signs", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha256-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA==='", >+ expectedResult: DoNotRunInlineScript, >+}, >+{ >+ name: "Malformed hash source", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha256-", >+ expectedResult: DoNotRunInlineScript, >+}, >+{ >+ name: "Hash source without hash", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha256-'", >+ expectedResult: DoNotRunInlineScript, >+}, >+{ >+ name: "Hash source without invalid hash", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha256-#'", >+ expectedResult: DoNotRunInlineScript, >+}, >+{ >+ name: "Hash source without invalid hash2", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha256-abc&='", >+ expectedResult: DoNotRunInlineScript, >+}, >+{ >+ name: "Hash source without invalid hash3", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha256-abc&=='", >+ expectedResult: DoNotRunInlineScript, >+}, >+{ >+ name: "Hash that is larger that 64 bytes", >+ charset: "UTF8", >+ script: encodeURIComponent("didRunInlineScript = true;"), >+ hashSource: "'sha256-LyogVGhpcyBpcyBhIGxvbmcgY29tbWVudCB0aGF0IHdpbGwgYmUgZW5jb2RlZCB1c2luZyBCYXNlNjQgdG8gcHJvZHVjZSBhbiBlbmNvZGVkIHN0cmluZyBvdXRwdXQgdGhhdCBpcyBsb25nZXIgdGhhbiBhIFNlY3VyZSBIYXNoIEFsZ29yaXRobS01MTIgZGlnZXN0LiAqLw=='", >+ expectedResult: DoNotRunInlineScript, >+}, >+]; >+ >+var indexOfCurrentTest = -1; >+var frame; >+ >+function testsFinished() >+{ >+ document.body.removeChild(frame); >+ finishJSTest(); >+} >+ >+function checkResult(didRunInlineScript) >+{ >+ var test = tests[indexOfCurrentTest]; >+ var expectedResult = test.expectedResult; >+ var message; >+ if (expectedResult === didRunInlineScript) { >+ if (expectedResult === RunInlineScript) >+ message = "did run inline script."; >+ else >+ message = "did not run inline script."; >+ testPassed('"' + test.name + '" ' + message); >+ } else { >+ if (expectedResult === RunInlineScript) >+ message = "should have run inline script. But did not."; >+ else >+ message = "should not have ran inline script. But did."; >+ testFailed('"' + test.name + '" ' + message); >+ } >+ runNextTest(); >+} >+ >+function runNextTest() >+{ >+ if (++indexOfCurrentTest >= tests.length) { >+ testsFinished(); >+ return; >+ } >+ var test = tests[indexOfCurrentTest]; >+ var queryStringArguments = { >+ charset: encodeURIComponent(test.charset), >+ script: test.script, // The test is responsible for URL encoding this value. >+ hashSource: encodeURIComponent(test.hashSource), >+ }; >+ var queryString = Object.keys(queryStringArguments).map(function (key) { return key + "=" + queryStringArguments[key]; }).join("&"); >+ frame.src = "http://127.0.0.1:8000/security/contentSecurityPolicy/1.1/resources/testScriptHash.php?" + queryString; >+} >+ >+window.onload = function () >+{ >+ frame = document.getElementById("frame"); >+ runNextTest(); >+} >+</script> >+</head> >+<body> >+<script> >+ description("This tests that script hashes work and conform to the Content Security Policy 2.0 specification."); >+</script> >+<iframe id="frame"></iframe> >+<script src="/js-test-resources/js-test-post.js"></script> >+</body> >+</html> >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-unicode-normalization.html b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-unicode-normalization.html >index b8264b4112298f074664f2e051580d367f601864..0048ffc1dc91b0b3abcb1c5fecda219bb36b536c 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-unicode-normalization.html >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-unicode-normalization.html >@@ -2,7 +2,7 @@ > <html> > <head> > <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >- <meta http-equiv="Content-Security-Policy" content="script-src 'sha1-zv73epHrGLk/k/onuSBPoZAxzaA=' 'sha1-gbGNUiHncUNJ+diPbIoc+x6KrLo='"> >+ <meta http-equiv="Content-Security-Policy" content="script-src 'sha256-OBpkpZD3ME366d9wfdsWwYSvYORUMfT+bvUVI5XJzBw=' 'sha256-bYf1lsJFPmWnm4DhDJwwaEKKonw7TN3KLz5M8J0PpIE='"> > <script> > if (window.testRunner) > testRunner.dumpAsText(); >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-allowed-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-allowed-expected.txt >index 0e2767168ee836bde8994792b0fba3ebac9a84d3..9469788e8f2d057cf21aa67232fa438d03916487 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-allowed-expected.txt >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-allowed-expected.txt >@@ -1,11 +1,8 @@ >-ALERT: PASS (1/4): The '#p1' element's text is green, which means the style was correctly applied. >-ALERT: PASS (2/4): The '#p2' element's text is green, which means the style was correctly applied. >-ALERT: PASS (3/4): The '#p3' element's text is green, which means the style was correctly applied. >-ALERT: PASS (4/4): The '#p4' element's text is green, which means the style was correctly applied. >+ALERT: PASS (1/3): The '#p1' element's text is green, which means the style was correctly applied. >+ALERT: PASS (2/3): The '#p2' element's text is green, which means the style was correctly applied. >+ALERT: PASS (3/3): The '#p3' element's text is green, which means the style was correctly applied. > This tests the result of a valid style hash. It passes if this text is green, and a "PASS" alert for p1 is fired. > > This tests the result of a valid style hash. It passes if this text is green, and a "PASS" alert for p2 is fired. > > This tests the result of a valid style hash. It passes if this text is green, and a "PASS" alert for p3 is fired. >- >-This tests the result of a valid style hash. It passes if this text is green, and a "PASS" alert for p4 is fired. >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-allowed.html b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-allowed.html >index ebc1fa22feea9ced057aeea63e5d9fef2774bb71..c3ab5d295b200f3ba153c802636cfb372b8b57da 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-allowed.html >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-allowed.html >@@ -1,44 +1,36 @@ > <!DOCTYPE html> > <html> > <head> >- <meta http-equiv="Content-Security-Policy" content="style-src 'sha1-eYyYGmKWdhpUewohaXk9o8IaLSw=' 'sha256-hndjYvzUzy2Ykuad81Cwsl1FOXX/qYs/aDVyUyNZwBw=' 'sha384-bSVm1i3sjPBRM4TwZtYTDjk9JxZMExYHWbFmP1SxDhJH4ue0Wu9OPOkY5hcqRcSt' 'sha512-440MmBLtj9Kp5Bqloogn9BqGDylY8vFsv5/zXL1zH2fJVssCoskRig4gyM+9KqwvCSapSz5CVoUGHQcxv43UQg=='"> >+ <meta http-equiv="Content-Security-Policy" content="style-src 'sha256-pAKi9r4/WB7fHydbE3F3t8i8602ij2JN8zHJpL2T5BM=' 'sha384-24Tf5u9STWAAJB2RRvecrrMSPtgnGnL8lx/mnxBm9P1mSHLW01CGK2U5WL6SAI/A' 'sha512-0x+WTjqWkJm9la1gVWtFpuSjwY+f1bJMQukr+nPcc3bgGSxakvxY01D7UvR4qEKEo/PWfsmJOgH2i8GKBFMYMQ=='"> > </head> > <body> > <p id="p1">This tests the result of a valid style hash. It passes if this text is green, and a "PASS" alert for p1 is fired.</p> > <p id="p2">This tests the result of a valid style hash. It passes if this text is green, and a "PASS" alert for p2 is fired.</p> > <p id="p3">This tests the result of a valid style hash. It passes if this text is green, and a "PASS" alert for p3 is fired.</p> >- <p id="p4">This tests the result of a valid style hash. It passes if this text is green, and a "PASS" alert for p4 is fired.</p> > <style>p#p1 { color: green; }</style> > <style>p#p2 { color: green; }</style> > <style>p#p3 { color: green; }</style> >- <style>p#p4 { color: green; }</style> > <script> > if (window.testRunner) > testRunner.dumpAsText(); > > var color = window.getComputedStyle(document.querySelector('#p1')).color; > if (color === "rgb(0, 128, 0)") >- alert("PASS (1/4): The '#p1' element's text is green, which means the style was correctly applied."); >+ alert("PASS (1/3): The '#p1' element's text is green, which means the style was correctly applied."); > else >- alert("FAIL (1/4): The '#p1' element's text is " + color + ", which means the style was incorrectly applied."); >+ alert("FAIL (1/3): The '#p1' element's text is " + color + ", which means the style was incorrectly applied."); > > var color = window.getComputedStyle(document.querySelector('#p2')).color; > if (color === "rgb(0, 128, 0)") >- alert("PASS (2/4): The '#p2' element's text is green, which means the style was correctly applied."); >+ alert("PASS (2/3): The '#p2' element's text is green, which means the style was correctly applied."); > else >- alert("FAIL (2/4): The '#p2' element's text is " + color + ", which means the style was incorrectly applied."); >+ alert("FAIL (2/3): The '#p2' element's text is " + color + ", which means the style was incorrectly applied."); > > var color = window.getComputedStyle(document.querySelector('#p3')).color; > if (color === "rgb(0, 128, 0)") >- alert("PASS (3/4): The '#p3' element's text is green, which means the style was correctly applied."); >+ alert("PASS (3/3): The '#p3' element's text is green, which means the style was correctly applied."); > else >- alert("FAIL (3/4): The '#p3' element's text is " + color + ", which means the style was incorrectly applied."); >- >- var color = window.getComputedStyle(document.querySelector('#p4')).color; >- if (color === "rgb(0, 128, 0)") >- alert("PASS (4/4): The '#p4' element's text is green, which means the style was correctly applied."); >- else >- alert("FAIL (4/4): The '#p4' element's text is " + color + ", which means the style was incorrectly applied."); >+ alert("FAIL (3/3): The '#p3' element's text is " + color + ", which means the style was incorrectly applied."); > </script> > </body> > </html> >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked-error-event.html b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked-error-event.html >index 4b48e00699a4f515780e5adac790414f4751e097..1a9bdaf18073866838995d14903da2f8617d33b6 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked-error-event.html >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked-error-event.html >@@ -2,7 +2,7 @@ > <html> > <head> > <title>Style element has error on bad style hash</title> >- <meta http-equiv="Content-Security-Policy" content="style-src 'sha1-pfeR5wMA6np45oqDTP6Pj3tLpJo='"> >+ <meta http-equiv="Content-Security-Policy" content="style-src 'sha256-FSRZotz4y83Ib8ZaoVj9eXKaeWXVUawM8zAPfYeYySs='"> > <script src="/js-test-resources/testharness.js"></script> > <script src="/js-test-resources/testharnessreport.js"></script> > <script> >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked-expected.txt >index ec6c8fffaeb933dace5ec9786a972faf47d86dcd..ed375298f6a4b4b9e7308c1e9ef69475830805ec 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked-expected.txt >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked-expected.txt >@@ -1,8 +1,8 @@ >-CONSOLE MESSAGE: line 6: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'sha1-pfeR5wMA6np45oqDTP6Pj3tLpJo='". Either the 'unsafe-inline' keyword, a hash ('sha256-pckGv9YvNcB5xy+Y4fbqhyo+ib850wyiuWeNbZvLi00='), or a nonce ('nonce-...') is required to enable inline execution. >+CONSOLE MESSAGE: line 6: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'sha256-FSRZotz4y83Ib8ZaoVj9eXKaeWXVUawM8zAPfYeYySs='". > >-CONSOLE MESSAGE: line 7: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'sha1-pfeR5wMA6np45oqDTP6Pj3tLpJo='". Either the 'unsafe-inline' keyword, a hash ('sha256-QtAhp+kqgljyNFcV4FsL0pofPI/L7IVXid6JT5PtsZA='), or a nonce ('nonce-...') is required to enable inline execution. >+CONSOLE MESSAGE: line 7: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'sha256-FSRZotz4y83Ib8ZaoVj9eXKaeWXVUawM8zAPfYeYySs='". > >-CONSOLE MESSAGE: line 8: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'sha1-pfeR5wMA6np45oqDTP6Pj3tLpJo='". Either the 'unsafe-inline' keyword, a hash ('sha256-QSqLgiKqPxCeZH1d3vWR+4HJOthCVhvG1P/AFaVJfR4='), or a nonce ('nonce-...') is required to enable inline execution. >+CONSOLE MESSAGE: line 8: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'sha256-FSRZotz4y83Ib8ZaoVj9eXKaeWXVUawM8zAPfYeYySs='". > > ALERT: PASS: The 'p' element's text is green, which means the style was correctly applied. > This tests the effect of a valid style-hash value, with one valid style and several invalid ones. It passes if the valid style is applied and three console warnings are visible. >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked.html b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked.html >index 7ffb475e9b28a44f25c41d9af76e5f610f896b2b..b41f12cb137631310ce1d8da3f40d37260786f69 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked.html >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked.html >@@ -1,7 +1,7 @@ > <!DOCTYPE html> > <html> > <head> >- <meta http-equiv="Content-Security-Policy" content="style-src 'sha1-pfeR5wMA6np45oqDTP6Pj3tLpJo='"> >+ <meta http-equiv="Content-Security-Policy" content="style-src 'sha256-FSRZotz4y83Ib8ZaoVj9eXKaeWXVUawM8zAPfYeYySs='"> > <style>p { color: green; }</style> > <style>p { color: red; }</style> > <style>p { color: purple; }</style> >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-default-src-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-default-src-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..cdbd5ad58b00606ff500d3fa8b37ce38e1eb5378 >--- /dev/null >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-default-src-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS Style Hash allow hash in default-src >+ >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-svg-style-basic-blocked-error-event.html b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-svg-style-basic-blocked-error-event.html >index 18ca8a2dd99347983a5dca03c187b6fcac94928a..664540e345c5ecc9e6847c8b74b2431632841317 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-svg-style-basic-blocked-error-event.html >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylehash-svg-style-basic-blocked-error-event.html >@@ -2,7 +2,7 @@ > <html> > <head> > <title>SVG Style element has error on bad style hash</title> >- <meta http-equiv="Content-Security-Policy" content="style-src 'sha1-pfeR5wMA6np45oqDTP6Pj3tLpJo='"> >+ <meta http-equiv="Content-Security-Policy" content="style-src 'sha256-FSRZotz4y83Ib8ZaoVj9eXKaeWXVUawM8zAPfYeYySs='"> > <script src="/js-test-resources/testharness.js"></script> > <script src="/js-test-resources/testharnessreport.js"></script> > <script>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 155007
:
273027
|
273335
|
273412
|
273515