1 /* 2 * Copyright (C) 2011 Google, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #ifndef ContentSecurityPolicy_h 27 #define ContentSecurityPolicy_h 28 29 #include "bindings/core/v8/ScriptState.h" 30 #include "core/dom/ExecutionContext.h" 31 #include "core/frame/ConsoleTypes.h" 32 #include "platform/network/ContentSecurityPolicyParsers.h" 33 #include "platform/network/HTTPParsers.h" 34 #include "platform/weborigin/ReferrerPolicy.h" 35 #include "wtf/HashSet.h" 36 #include "wtf/PassOwnPtr.h" 37 #include "wtf/PassRefPtr.h" 38 #include "wtf/RefCounted.h" 39 #include "wtf/Vector.h" 40 #include "wtf/text/StringHash.h" 41 #include "wtf/text/TextPosition.h" 42 #include "wtf/text/WTFString.h" 43 44 namespace WTF { 45 class OrdinalNumber; 46 } 47 48 namespace blink { 49 50 class ContentSecurityPolicyResponseHeaders; 51 class ConsoleMessage; 52 class CSPDirectiveList; 53 class CSPSource; 54 class Document; 55 class KURL; 56 class SecurityOrigin; 57 58 typedef int SandboxFlags; 59 typedef Vector<OwnPtr<CSPDirectiveList> > CSPDirectiveListVector; 60 typedef WillBePersistentHeapVector<RefPtrWillBeMember<ConsoleMessage> > ConsoleMessageVector; 61 62 class ContentSecurityPolicy : public RefCounted<ContentSecurityPolicy> { 63 WTF_MAKE_FAST_ALLOCATED; 64 public: 65 // CSP 1.0 Directives 66 static const char ConnectSrc[]; 67 static const char DefaultSrc[]; 68 static const char FontSrc[]; 69 static const char FrameSrc[]; 70 static const char ImgSrc[]; 71 static const char MediaSrc[]; 72 static const char ObjectSrc[]; 73 static const char ReportURI[]; 74 static const char Sandbox[]; 75 static const char ScriptSrc[]; 76 static const char StyleSrc[]; 77 78 // CSP 1.1 Directives 79 static const char BaseURI[]; 80 static const char ChildSrc[]; 81 static const char FormAction[]; 82 static const char FrameAncestors[]; 83 static const char PluginTypes[]; 84 static const char ReflectedXSS[]; 85 static const char Referrer[]; 86 87 enum ReportingStatus { 88 SendReport, 89 SuppressReport 90 }; 91 create()92 static PassRefPtr<ContentSecurityPolicy> create() 93 { 94 return adoptRef(new ContentSecurityPolicy()); 95 } 96 ~ContentSecurityPolicy(); 97 98 void bindToExecutionContext(ExecutionContext*); 99 void copyStateFrom(const ContentSecurityPolicy*); 100 101 void didReceiveHeaders(const ContentSecurityPolicyResponseHeaders&); 102 void didReceiveHeader(const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource); 103 104 // These functions are wrong because they assume that there is only one header. 105 // FIXME: Replace them with functions that return vectors. 106 const String& deprecatedHeader() const; 107 ContentSecurityPolicyHeaderType deprecatedHeaderType() const; 108 109 bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const; 110 bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const; 111 bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const; 112 bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const; 113 bool allowEval(ScriptState* = 0, ReportingStatus = SendReport) const; 114 bool allowPluginType(const String& type, const String& typeAttribute, const KURL&, ReportingStatus = SendReport) const; 115 116 bool allowScriptFromSource(const KURL&, ReportingStatus = SendReport) const; 117 bool allowObjectFromSource(const KURL&, ReportingStatus = SendReport) const; 118 bool allowChildFrameFromSource(const KURL&, ReportingStatus = SendReport) const; 119 bool allowImageFromSource(const KURL&, ReportingStatus = SendReport) const; 120 bool allowStyleFromSource(const KURL&, ReportingStatus = SendReport) const; 121 bool allowFontFromSource(const KURL&, ReportingStatus = SendReport) const; 122 bool allowMediaFromSource(const KURL&, ReportingStatus = SendReport) const; 123 bool allowConnectToSource(const KURL&, ReportingStatus = SendReport) const; 124 bool allowFormAction(const KURL&, ReportingStatus = SendReport) const; 125 bool allowBaseURI(const KURL&, ReportingStatus = SendReport) const; 126 bool allowAncestors(LocalFrame*, const KURL&, ReportingStatus = SendReport) const; 127 bool allowChildContextFromSource(const KURL&, ReportingStatus = SendReport) const; 128 bool allowWorkerContextFromSource(const KURL&, ReportingStatus = SendReport) const; 129 130 // The nonce and hash allow functions are guaranteed to not have any side 131 // effects, including reporting. 132 // Nonce/Hash functions check all policies relating to use of a script/style 133 // with the given nonce/hash and return true all CSP policies allow it. 134 // If these return true, callers can then process the content or 135 // issue a load and be safe disabling any further CSP checks. 136 bool allowScriptWithNonce(const String& nonce) const; 137 bool allowStyleWithNonce(const String& nonce) const; 138 bool allowScriptWithHash(const String& source) const; 139 bool allowStyleWithHash(const String& source) const; 140 141 void usesScriptHashAlgorithms(uint8_t ContentSecurityPolicyHashAlgorithm); 142 void usesStyleHashAlgorithms(uint8_t ContentSecurityPolicyHashAlgorithm); 143 144 ReflectedXSSDisposition reflectedXSSDisposition() const; 145 146 ReferrerPolicy referrerPolicy() const; 147 bool didSetReferrerPolicy() const; 148 149 void setOverrideAllowInlineStyle(bool); 150 void setOverrideURLForSelf(const KURL&); 151 152 bool isActive() const; 153 154 // If a frame is passed in, the message will be logged to its active document's console. 155 // Otherwise, the message will be logged to this object's |m_executionContext|. 156 void logToConsole(PassRefPtrWillBeRawPtr<ConsoleMessage>, LocalFrame* = 0); 157 158 void reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression); 159 void reportDuplicateDirective(const String&); 160 void reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value); 161 void reportInvalidPathCharacter(const String& directiveName, const String& value, const char); 162 void reportInvalidPluginTypes(const String&); 163 void reportInvalidSandboxFlags(const String&); 164 void reportInvalidSourceExpression(const String& directiveName, const String& source); 165 void reportInvalidReflectedXSS(const String&); 166 void reportMissingReportURI(const String&); 167 void reportUnsupportedDirective(const String&); 168 void reportInvalidInReportOnly(const String&); 169 void reportInvalidReferrer(const String&); 170 void reportReportOnlyInMeta(const String&); 171 void reportMetaOutsideHead(const String&); 172 173 // If a frame is passed in, the report will be sent using it as a context. If no frame is 174 // passed in, the report will be sent via this object's |m_executionContext| (or dropped 175 // on the floor if no such context is available). 176 void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const Vector<String>& reportEndpoints, const String& header, LocalFrame* = 0); 177 178 void reportBlockedScriptExecutionToInspector(const String& directiveText) const; 179 180 const KURL url() const; 181 void enforceSandboxFlags(SandboxFlags); 182 String evalDisabledErrorMessage() const; 183 184 bool urlMatchesSelf(const KURL&) const; 185 bool protocolMatchesSelf(const KURL&) const; 186 187 bool experimentalFeaturesEnabled() const; 188 189 static bool shouldBypassMainWorld(ExecutionContext*); 190 191 static bool isDirectiveName(const String&); 192 193 private: 194 ContentSecurityPolicy(); 195 196 void applyPolicySideEffectsToExecutionContext(); 197 198 Document* document() const; 199 SecurityOrigin* securityOrigin() const; 200 KURL completeURL(const String&) const; 201 202 void logToConsole(const String& message, MessageLevel = ErrorMessageLevel); 203 void addPolicyFromHeaderValue(const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource); 204 205 bool shouldSendViolationReport(const String&) const; 206 void didSendViolationReport(const String&); 207 208 ExecutionContext* m_executionContext; 209 bool m_overrideInlineStyleAllowed; 210 CSPDirectiveListVector m_policies; 211 ConsoleMessageVector m_consoleMessages; 212 213 HashSet<unsigned, AlreadyHashed> m_violationReportsSent; 214 215 // We put the hash functions used on the policy object so that we only need 216 // to calculate a hash once and then distribute it to all of the directives 217 // for validation. 218 uint8_t m_scriptHashAlgorithmsUsed; 219 uint8_t m_styleHashAlgorithmsUsed; 220 221 // State flags used to configure the environment after parsing a policy. 222 SandboxFlags m_sandboxMask; 223 ReferrerPolicy m_referrerPolicy; 224 String m_disableEvalErrorMessage; 225 226 OwnPtr<CSPSource> m_selfSource; 227 }; 228 229 } 230 231 #endif 232