Remove duplicate MathML tests
[WebKit-https.git] / Source / WebCore / page / csp / ContentSecurityPolicy.h
1 /*
2  * Copyright (C) 2011 Google, Inc. All rights reserved.
3  * Copyright (C) 2016 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #pragma once
28
29 #include "ContentSecurityPolicyHash.h"
30 #include "ContentSecurityPolicyResponseHeaders.h"
31 #include "SecurityContext.h"
32 #include "SecurityOrigin.h"
33 #include "SecurityOriginHash.h"
34 #include <functional>
35 #include <wtf/HashSet.h>
36 #include <wtf/Vector.h>
37 #include <wtf/text/TextPosition.h>
38
39 namespace JSC {
40 class CallFrame;
41 using ExecState = CallFrame;
42 }
43
44 namespace WTF {
45 class OrdinalNumber;
46 }
47
48 namespace WebCore {
49
50 class ContentSecurityPolicyDirective;
51 class ContentSecurityPolicyDirectiveList;
52 class ContentSecurityPolicySource;
53 class DOMStringList;
54 class Frame;
55 class JSWindowProxy;
56 class ResourceRequest;
57 class ScriptExecutionContext;
58 class SecurityOrigin;
59 class TextEncoding;
60 struct ContentSecurityPolicyClient;
61
62 typedef Vector<std::unique_ptr<ContentSecurityPolicyDirectiveList>> CSPDirectiveListVector;
63
64 class ContentSecurityPolicy {
65     WTF_MAKE_FAST_ALLOCATED;
66 public:
67     explicit ContentSecurityPolicy(URL&&, ScriptExecutionContext&);
68     WEBCORE_EXPORT explicit ContentSecurityPolicy(URL&&, ContentSecurityPolicyClient* = nullptr);
69     WEBCORE_EXPORT ~ContentSecurityPolicy();
70
71     void copyStateFrom(const ContentSecurityPolicy*);
72     void copyUpgradeInsecureRequestStateFrom(const ContentSecurityPolicy&);
73     void createPolicyForPluginDocumentFrom(const ContentSecurityPolicy&);
74
75     void didCreateWindowProxy(JSWindowProxy&) const;
76
77     enum class PolicyFrom {
78         API,
79         HTTPEquivMeta,
80         HTTPHeader,
81         Inherited,
82         InheritedForPluginDocument,
83     };
84     WEBCORE_EXPORT ContentSecurityPolicyResponseHeaders responseHeaders() const;
85     enum ReportParsingErrors { No, Yes };
86     WEBCORE_EXPORT void didReceiveHeaders(const ContentSecurityPolicyResponseHeaders&, String&& referrer, ReportParsingErrors = ReportParsingErrors::Yes);
87     void didReceiveHeader(const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicy::PolicyFrom, String&& referrer, int httpStatusCode = 0);
88
89     bool allowScriptWithNonce(const String& nonce, bool overrideContentSecurityPolicy = false) const;
90     bool allowStyleWithNonce(const String& nonce, bool overrideContentSecurityPolicy = false) const;
91
92     bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false) const;
93     bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false) const;
94     bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, const String& scriptContent, bool overrideContentSecurityPolicy = false) const;
95     bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, const String& styleContent, bool overrideContentSecurityPolicy = false) const;
96
97     bool allowEval(JSC::ExecState*, bool overrideContentSecurityPolicy = false) const;
98
99     bool allowPluginType(const String& type, const String& typeAttribute, const URL&, bool overrideContentSecurityPolicy = false) const;
100
101     bool allowFrameAncestors(const Frame&, const URL&, bool overrideContentSecurityPolicy = false) const;
102     WEBCORE_EXPORT bool allowFrameAncestors(const Vector<RefPtr<SecurityOrigin>>& ancestorOrigins, const URL&, bool overrideContentSecurityPolicy = false) const;
103     WEBCORE_EXPORT bool overridesXFrameOptions() const;
104
105     enum class RedirectResponseReceived { No, Yes };
106     WEBCORE_EXPORT bool allowScriptFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
107     bool allowImageFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
108     bool allowStyleFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
109     bool allowFontFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
110 #if ENABLE(APPLICATION_MANIFEST)
111     bool allowManifestFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
112 #endif
113     bool allowMediaFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
114
115     bool allowChildFrameFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
116     WEBCORE_EXPORT bool allowChildContextFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
117     WEBCORE_EXPORT bool allowConnectToSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
118     bool allowFormAction(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
119
120     bool allowObjectFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
121     bool allowBaseURI(const URL&, bool overrideContentSecurityPolicy = false) const;
122
123     void setOverrideAllowInlineStyle(bool);
124
125     void gatherReportURIs(DOMStringList&) const;
126
127     bool allowRunningOrDisplayingInsecureContent(const URL&);
128
129     // The following functions are used by internal data structures to call back into this object when parsing, validating,
130     // and applying a Content Security Policy.
131     // FIXME: We should make the various directives serve only as state stores for the parsed policy and remove these functions.
132     // This class should traverse the directives, validating the policy, and applying it to the script execution context.
133
134     // Used by ContentSecurityPolicyMediaListDirective
135     void reportInvalidPluginTypes(const String&) const;
136
137     // Used by ContentSecurityPolicySourceList
138     void reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression) const;
139     void reportInvalidPathCharacter(const String& directiveName, const String& value, const char) const;
140     void reportInvalidSourceExpression(const String& directiveName, const String& source) const;
141     bool urlMatchesSelf(const URL&) const;
142     bool allowContentSecurityPolicySourceStarToMatchAnyProtocol() const;
143
144     // Used by ContentSecurityPolicyDirectiveList
145     void reportDuplicateDirective(const String&) const;
146     void reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const;
147     void reportInvalidSandboxFlags(const String&) const;
148     void reportInvalidDirectiveInReportOnlyMode(const String&) const;
149     void reportInvalidDirectiveInHTTPEquivMeta(const String&) const;
150     void reportMissingReportURI(const String&) const;
151     void reportUnsupportedDirective(const String&) const;
152     void enforceSandboxFlags(SandboxFlags sandboxFlags) { m_sandboxFlags |= sandboxFlags; }
153     void addHashAlgorithmsForInlineScripts(OptionSet<ContentSecurityPolicyHashAlgorithm> hashAlgorithmsForInlineScripts)
154     {
155         m_hashAlgorithmsForInlineScripts.add(hashAlgorithmsForInlineScripts);
156     }
157     void addHashAlgorithmsForInlineStylesheets(OptionSet<ContentSecurityPolicyHashAlgorithm> hashAlgorithmsForInlineStylesheets)
158     {
159         m_hashAlgorithmsForInlineStylesheets.add(hashAlgorithmsForInlineStylesheets);
160     }
161
162     // Used by ContentSecurityPolicySource
163     bool protocolMatchesSelf(const URL&) const;
164
165     void setUpgradeInsecureRequests(bool);
166     bool upgradeInsecureRequests() const { return m_upgradeInsecureRequests; }
167     enum class InsecureRequestType { Load, FormSubmission, Navigation };
168     WEBCORE_EXPORT void upgradeInsecureRequestIfNeeded(ResourceRequest&, InsecureRequestType) const;
169     WEBCORE_EXPORT void upgradeInsecureRequestIfNeeded(URL&, InsecureRequestType) const;
170
171     HashSet<SecurityOriginData> takeNavigationRequestsToUpgrade();
172     void inheritInsecureNavigationRequestsToUpgradeFromOpener(const ContentSecurityPolicy&);
173     void setInsecureNavigationRequestsToUpgrade(HashSet<SecurityOriginData>&&);
174
175     void setClient(ContentSecurityPolicyClient* client) { m_client = client; }
176     void updateSourceSelf(const SecurityOrigin&);
177
178 private:
179     void logToConsole(const String& message, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), const WTF::OrdinalNumber& contextColumn = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const;
180     void applyPolicyToScriptExecutionContext();
181
182     // Implements the deprecated CSP2 "strip uri for reporting" algorithm from <https://www.w3.org/TR/CSP2/#violation-reports>.
183     String deprecatedURLForReporting(const URL&) const;
184
185     const TextEncoding& documentEncoding() const;
186
187     enum class Disposition {
188         Enforce,
189         ReportOnly,
190     };
191
192     using ViolatedDirectiveCallback = std::function<void (const ContentSecurityPolicyDirective&)>;
193
194     template<typename Predicate, typename... Args>
195     typename std::enable_if<!std::is_convertible<Predicate, ViolatedDirectiveCallback>::value, bool>::type allPoliciesWithDispositionAllow(Disposition, Predicate&&, Args&&...) const;
196
197     template<typename Predicate, typename... Args>
198     bool allPoliciesWithDispositionAllow(Disposition, ViolatedDirectiveCallback&&, Predicate&&, Args&&...) const;
199
200     template<typename Predicate, typename... Args>
201     bool allPoliciesAllow(ViolatedDirectiveCallback&&, Predicate&&, Args&&...) const WARN_UNUSED_RETURN;
202
203     using ResourcePredicate = const ContentSecurityPolicyDirective *(ContentSecurityPolicyDirectiveList::*)(const URL &, bool) const;
204     bool allowResourceFromSource(const URL&, RedirectResponseReceived, const char*, ResourcePredicate) const;
205
206     using HashInEnforcedAndReportOnlyPoliciesPair = std::pair<bool, bool>;
207     template<typename Predicate> HashInEnforcedAndReportOnlyPoliciesPair findHashOfContentInPolicies(Predicate&&, const String& content, OptionSet<ContentSecurityPolicyHashAlgorithm>) const WARN_UNUSED_RETURN;
208
209     void reportViolation(const String& effectiveViolatedDirective, const ContentSecurityPolicyDirective& violatedDirective, const URL& blockedURL, const String& consoleMessage, JSC::ExecState*) const;
210     void reportViolation(const String& effectiveViolatedDirective, const String& violatedDirective, const ContentSecurityPolicyDirectiveList&, const URL& blockedURL, const String& consoleMessage, JSC::ExecState* = nullptr) const;
211     void reportViolation(const String& effectiveViolatedDirective, const ContentSecurityPolicyDirective& violatedDirective, const URL& blockedURL, const String& consoleMessage, const String& sourceURL, const TextPosition& sourcePosition, JSC::ExecState* = nullptr) const;
212     void reportViolation(const String& effectiveViolatedDirective, const String& violatedDirective, const ContentSecurityPolicyDirectiveList& violatedDirectiveList, const URL& blockedURL, const String& consoleMessage, const String& sourceURL, const TextPosition& sourcePosition, JSC::ExecState*) const;
213     void reportBlockedScriptExecutionToInspector(const String& directiveText) const;
214
215     // We can never have both a script execution context and a ContentSecurityPolicyClient.
216     ScriptExecutionContext* m_scriptExecutionContext { nullptr };
217     ContentSecurityPolicyClient* m_client { nullptr };
218     URL m_protectedURL;
219     std::unique_ptr<ContentSecurityPolicySource> m_selfSource;
220     String m_selfSourceProtocol;
221     CSPDirectiveListVector m_policies;
222     String m_lastPolicyEvalDisabledErrorMessage;
223     String m_lastPolicyWebAssemblyDisabledErrorMessage;
224     String m_referrer;
225     SandboxFlags m_sandboxFlags { SandboxNone };
226     bool m_overrideInlineStyleAllowed { false };
227     bool m_isReportingEnabled { true };
228     bool m_upgradeInsecureRequests { false };
229     bool m_hasAPIPolicy { false };
230     int m_httpStatusCode { 0 };
231     OptionSet<ContentSecurityPolicyHashAlgorithm> m_hashAlgorithmsForInlineScripts;
232     OptionSet<ContentSecurityPolicyHashAlgorithm> m_hashAlgorithmsForInlineStylesheets;
233     HashSet<SecurityOriginData> m_insecureNavigationRequestsToUpgrade;
234     mutable Optional<ContentSecurityPolicyResponseHeaders> m_cachedResponseHeaders;
235 };
236
237 }