| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CSPDirectiveList_h |
| #define CSPDirectiveList_h |
| |
| #include "core/frame/csp/ContentSecurityPolicy.h" |
| #include "core/frame/csp/MediaListDirective.h" |
| #include "core/frame/csp/SourceListDirective.h" |
| #include "platform/heap/Handle.h" |
| #include "platform/loader/fetch/Resource.h" |
| #include "platform/loader/fetch/ResourceRequest.h" |
| #include "platform/network/ContentSecurityPolicyParsers.h" |
| #include "platform/network/HTTPParsers.h" |
| #include "platform/weborigin/KURL.h" |
| #include "platform/weborigin/SecurityViolationReportingPolicy.h" |
| #include "public/platform/WebContentSecurityPolicy.h" |
| #include "wtf/Vector.h" |
| #include "wtf/text/AtomicString.h" |
| #include "wtf/text/WTFString.h" |
| |
| namespace blink { |
| |
| class ContentSecurityPolicy; |
| |
| typedef HeapVector<Member<SourceListDirective>> SourceListDirectiveVector; |
| |
| class CORE_EXPORT CSPDirectiveList |
| : public GarbageCollectedFinalized<CSPDirectiveList> { |
| WTF_MAKE_NONCOPYABLE(CSPDirectiveList); |
| |
| public: |
| static CSPDirectiveList* create(ContentSecurityPolicy*, |
| const UChar* begin, |
| const UChar* end, |
| ContentSecurityPolicyHeaderType, |
| ContentSecurityPolicyHeaderSource); |
| |
| void parse(const UChar* begin, const UChar* end); |
| |
| const String& header() const { return m_header; } |
| ContentSecurityPolicyHeaderType headerType() const { return m_headerType; } |
| ContentSecurityPolicyHeaderSource headerSource() const { |
| return m_headerSource; |
| } |
| |
| bool allowJavaScriptURLs(Element*, |
| const String& source, |
| const String& contextURL, |
| const WTF::OrdinalNumber& contextLine, |
| SecurityViolationReportingPolicy) const; |
| bool allowInlineEventHandlers(Element*, |
| const String& source, |
| const String& contextURL, |
| const WTF::OrdinalNumber& contextLine, |
| SecurityViolationReportingPolicy) const; |
| bool allowInlineScript(Element*, |
| const String& contextURL, |
| const String& nonce, |
| const WTF::OrdinalNumber& contextLine, |
| SecurityViolationReportingPolicy, |
| const String& scriptContent) const; |
| bool allowInlineStyle(Element*, |
| const String& contextURL, |
| const String& nonce, |
| const WTF::OrdinalNumber& contextLine, |
| SecurityViolationReportingPolicy, |
| const String& styleContent) const; |
| bool allowEval(ScriptState*, |
| SecurityViolationReportingPolicy, |
| ContentSecurityPolicy::ExceptionStatus = |
| ContentSecurityPolicy::WillNotThrowException) const; |
| bool allowPluginType(const String& type, |
| const String& typeAttribute, |
| const KURL&, |
| SecurityViolationReportingPolicy) const; |
| |
| bool allowScriptFromSource(const KURL&, |
| const String& nonce, |
| const IntegrityMetadataSet& hashes, |
| ParserDisposition, |
| ResourceRequest::RedirectStatus, |
| SecurityViolationReportingPolicy) const; |
| bool allowStyleFromSource(const KURL&, |
| const String& nonce, |
| ResourceRequest::RedirectStatus, |
| SecurityViolationReportingPolicy) const; |
| |
| bool allowObjectFromSource(const KURL&, |
| ResourceRequest::RedirectStatus, |
| SecurityViolationReportingPolicy) const; |
| bool allowFrameFromSource(const KURL&, |
| ResourceRequest::RedirectStatus, |
| SecurityViolationReportingPolicy) const; |
| bool allowImageFromSource(const KURL&, |
| ResourceRequest::RedirectStatus, |
| SecurityViolationReportingPolicy) const; |
| bool allowFontFromSource(const KURL&, |
| ResourceRequest::RedirectStatus, |
| SecurityViolationReportingPolicy) const; |
| bool allowMediaFromSource(const KURL&, |
| ResourceRequest::RedirectStatus, |
| SecurityViolationReportingPolicy) const; |
| bool allowManifestFromSource(const KURL&, |
| ResourceRequest::RedirectStatus, |
| SecurityViolationReportingPolicy) const; |
| bool allowConnectToSource(const KURL&, |
| ResourceRequest::RedirectStatus, |
| SecurityViolationReportingPolicy) const; |
| bool allowFormAction(const KURL&, |
| ResourceRequest::RedirectStatus, |
| SecurityViolationReportingPolicy) const; |
| bool allowBaseURI(const KURL&, |
| ResourceRequest::RedirectStatus, |
| SecurityViolationReportingPolicy) const; |
| bool allowWorkerFromSource(const KURL&, |
| ResourceRequest::RedirectStatus, |
| SecurityViolationReportingPolicy) const; |
| // |allowAncestors| does not need to know whether the resource was a |
| // result of a redirect. After a redirect, source paths are usually |
| // ignored to stop a page from learning the path to which the |
| // request was redirected, but this is not a concern for ancestors, |
| // because a child frame can't manipulate the URL of a cross-origin |
| // parent. |
| bool allowAncestors(LocalFrame*, |
| const KURL&, |
| SecurityViolationReportingPolicy) const; |
| bool allowScriptHash(const CSPHashValue&, |
| ContentSecurityPolicy::InlineType) const; |
| bool allowStyleHash(const CSPHashValue&, |
| ContentSecurityPolicy::InlineType) const; |
| bool allowDynamic() const; |
| bool allowDynamicWorker() const; |
| |
| bool allowRequestWithoutIntegrity(WebURLRequest::RequestContext, |
| const KURL&, |
| ResourceRequest::RedirectStatus, |
| SecurityViolationReportingPolicy) const; |
| |
| bool strictMixedContentChecking() const { |
| return m_strictMixedContentCheckingEnforced; |
| } |
| void reportMixedContent(const KURL& mixedURL, |
| ResourceRequest::RedirectStatus) const; |
| |
| const String& evalDisabledErrorMessage() const { |
| return m_evalDisabledErrorMessage; |
| } |
| bool isReportOnly() const { |
| return m_headerType == ContentSecurityPolicyHeaderTypeReport; |
| } |
| const Vector<String>& reportEndpoints() const { return m_reportEndpoints; } |
| uint8_t requireSRIForTokens() const { return m_requireSRIFor; } |
| bool isFrameAncestorsEnforced() const { |
| return m_frameAncestors.get() && !isReportOnly(); |
| } |
| |
| // Used to copy plugin-types into a plugin document in a nested |
| // browsing context. |
| bool hasPluginTypes() const { return !!m_pluginTypes; } |
| const String& pluginTypesText() const; |
| |
| bool shouldSendCSPHeader(Resource::Type) const; |
| |
| // The algorithm is described here: |
| // https://w3c.github.io/webappsec-csp/embedded/#subsume-policy |
| bool subsumes(const CSPDirectiveListVector&); |
| |
| // Export a subset of the Policy. The primary goal of this method is to make |
| // the embedders aware of the directives that affect navigation, as the |
| // embedder is responsible for navigational enforcement. |
| // It currently contains the following ones: |
| // * default-src |
| // * child-src |
| // * frame-src |
| // * form-action |
| // The exported directives only contains sources that affect navigation. For |
| // instance it doesn't contains 'unsafe-inline' or 'unsafe-eval' |
| WebContentSecurityPolicy exposeForNavigationalChecks() const; |
| |
| DECLARE_TRACE(); |
| |
| private: |
| FRIEND_TEST_ALL_PREFIXES(CSPDirectiveListTest, IsMatchingNoncePresent); |
| FRIEND_TEST_ALL_PREFIXES(CSPDirectiveListTest, GetSourceVector); |
| FRIEND_TEST_ALL_PREFIXES(CSPDirectiveListTest, OperativeDirectiveGivenType); |
| |
| enum RequireSRIForToken { None = 0, Script = 1 << 0, Style = 1 << 1 }; |
| |
| CSPDirectiveList(ContentSecurityPolicy*, |
| ContentSecurityPolicyHeaderType, |
| ContentSecurityPolicyHeaderSource); |
| |
| bool parseDirective(const UChar* begin, |
| const UChar* end, |
| String& name, |
| String& value); |
| void parseRequireSRIFor(const String& name, const String& value); |
| void parseReportURI(const String& name, const String& value); |
| void parsePluginTypes(const String& name, const String& value); |
| void addDirective(const String& name, const String& value); |
| void applySandboxPolicy(const String& name, const String& sandboxPolicy); |
| void enforceStrictMixedContentChecking(const String& name, |
| const String& value); |
| void enableInsecureRequestsUpgrade(const String& name, const String& value); |
| void treatAsPublicAddress(const String& name, const String& value); |
| |
| template <class CSPDirectiveType> |
| void setCSPDirective(const String& name, |
| const String& value, |
| Member<CSPDirectiveType>&); |
| |
| SourceListDirective* operativeDirective(SourceListDirective*) const; |
| SourceListDirective* operativeDirective(SourceListDirective*, |
| SourceListDirective* override) const; |
| void reportViolation(const String& directiveText, |
| const ContentSecurityPolicy::DirectiveType&, |
| const String& consoleMessage, |
| const KURL& blockedURL, |
| ResourceRequest::RedirectStatus) const; |
| void reportViolationWithFrame(const String& directiveText, |
| const ContentSecurityPolicy::DirectiveType&, |
| const String& consoleMessage, |
| const KURL& blockedURL, |
| LocalFrame*) const; |
| void reportViolationWithLocation(const String& directiveText, |
| const ContentSecurityPolicy::DirectiveType&, |
| const String& consoleMessage, |
| const KURL& blockedURL, |
| const String& contextURL, |
| const WTF::OrdinalNumber& contextLine, |
| Element*, |
| const String& source) const; |
| void reportViolationWithState( |
| const String& directiveText, |
| const ContentSecurityPolicy::DirectiveType&, |
| const String& message, |
| const KURL& blockedURL, |
| ScriptState*, |
| const ContentSecurityPolicy::ExceptionStatus) const; |
| |
| bool checkEval(SourceListDirective*) const; |
| bool checkDynamic(SourceListDirective*) const; |
| bool isMatchingNoncePresent(SourceListDirective*, const String&) const; |
| bool areAllMatchingHashesPresent(SourceListDirective*, |
| const IntegrityMetadataSet&) const; |
| bool checkHash(SourceListDirective*, const CSPHashValue&) const; |
| bool checkHashedAttributes(SourceListDirective*) const; |
| bool checkSource(SourceListDirective*, |
| const KURL&, |
| ResourceRequest::RedirectStatus) const; |
| bool checkMediaType(MediaListDirective*, |
| const String& type, |
| const String& typeAttribute) const; |
| bool checkAncestors(SourceListDirective*, LocalFrame*) const; |
| bool checkRequestWithoutIntegrity(WebURLRequest::RequestContext) const; |
| |
| void setEvalDisabledErrorMessage(const String& errorMessage) { |
| m_evalDisabledErrorMessage = errorMessage; |
| } |
| |
| bool checkEvalAndReportViolation( |
| SourceListDirective*, |
| const String& consoleMessage, |
| ScriptState*, |
| ContentSecurityPolicy::ExceptionStatus = |
| ContentSecurityPolicy::WillNotThrowException) const; |
| bool checkInlineAndReportViolation(SourceListDirective*, |
| const String& consoleMessage, |
| Element*, |
| const String& source, |
| const String& contextURL, |
| const WTF::OrdinalNumber& contextLine, |
| bool isScript, |
| const String& hashValue) const; |
| |
| bool checkSourceAndReportViolation( |
| SourceListDirective*, |
| const KURL&, |
| const ContentSecurityPolicy::DirectiveType&, |
| ResourceRequest::RedirectStatus) const; |
| bool checkMediaTypeAndReportViolation(MediaListDirective*, |
| const String& type, |
| const String& typeAttribute, |
| const String& consoleMessage) const; |
| bool checkAncestorsAndReportViolation(SourceListDirective*, |
| LocalFrame*, |
| const KURL&) const; |
| bool checkRequestWithoutIntegrityAndReportViolation( |
| WebURLRequest::RequestContext, |
| const KURL&, |
| ResourceRequest::RedirectStatus) const; |
| |
| bool denyIfEnforcingPolicy() const { return isReportOnly(); } |
| |
| // This function returns a SourceListDirective of a given type |
| // or if it is not defined, the default SourceListDirective for that type. |
| SourceListDirective* operativeDirective( |
| const ContentSecurityPolicy::DirectiveType&) const; |
| |
| // This function aggregates from a vector of policies all operative |
| // SourceListDirectives of a given type into a vector. |
| static SourceListDirectiveVector getSourceVector( |
| const ContentSecurityPolicy::DirectiveType&, |
| const CSPDirectiveListVector& policies); |
| |
| Member<ContentSecurityPolicy> m_policy; |
| |
| String m_header; |
| ContentSecurityPolicyHeaderType m_headerType; |
| ContentSecurityPolicyHeaderSource m_headerSource; |
| |
| bool m_hasSandboxPolicy; |
| |
| bool m_strictMixedContentCheckingEnforced; |
| |
| bool m_upgradeInsecureRequests; |
| bool m_treatAsPublicAddress; |
| |
| Member<MediaListDirective> m_pluginTypes; |
| Member<SourceListDirective> m_baseURI; |
| Member<SourceListDirective> m_childSrc; |
| Member<SourceListDirective> m_connectSrc; |
| Member<SourceListDirective> m_defaultSrc; |
| Member<SourceListDirective> m_fontSrc; |
| Member<SourceListDirective> m_formAction; |
| Member<SourceListDirective> m_frameAncestors; |
| Member<SourceListDirective> m_frameSrc; |
| Member<SourceListDirective> m_imgSrc; |
| Member<SourceListDirective> m_mediaSrc; |
| Member<SourceListDirective> m_manifestSrc; |
| Member<SourceListDirective> m_objectSrc; |
| Member<SourceListDirective> m_scriptSrc; |
| Member<SourceListDirective> m_styleSrc; |
| Member<SourceListDirective> m_workerSrc; |
| |
| uint8_t m_requireSRIFor; |
| |
| Vector<String> m_reportEndpoints; |
| |
| String m_evalDisabledErrorMessage; |
| }; |
| |
| } // namespace blink |
| |
| #endif |