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/v8/ScriptState.h" 30 #include "core/dom/Document.h" 31 #include "core/dom/ExecutionContext.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 WebCore { 49 50 class ContentSecurityPolicyResponseHeaders; 51 class CSPDirectiveList; 52 class DOMStringList; 53 class JSONObject; 54 class KURL; 55 class SecurityOrigin; 56 57 typedef int SandboxFlags; 58 typedef Vector<OwnPtr<CSPDirectiveList> > CSPDirectiveListVector; 59 60 class ContentSecurityPolicy : public RefCounted<ContentSecurityPolicy> { 61 WTF_MAKE_FAST_ALLOCATED; 62 public: 63 // CSP 1.0 Directives 64 static const char ConnectSrc[]; 65 static const char DefaultSrc[]; 66 static const char FontSrc[]; 67 static const char FrameSrc[]; 68 static const char ImgSrc[]; 69 static const char MediaSrc[]; 70 static const char ObjectSrc[]; 71 static const char ReportURI[]; 72 static const char Sandbox[]; 73 static const char ScriptSrc[]; 74 static const char StyleSrc[]; 75 76 // CSP 1.1 Directives 77 static const char BaseURI[]; 78 static const char ChildSrc[]; 79 static const char FormAction[]; 80 static const char FrameAncestors[]; 81 static const char PluginTypes[]; 82 static const char ReflectedXSS[]; 83 static const char Referrer[]; 84 create(ExecutionContext * executionContext)85 static PassRefPtr<ContentSecurityPolicy> create(ExecutionContext* executionContext) 86 { 87 return adoptRef(new ContentSecurityPolicy(executionContext)); 88 } 89 ~ContentSecurityPolicy(); 90 91 void copyStateFrom(const ContentSecurityPolicy*); 92 93 enum ReportingStatus { 94 SendReport, 95 SuppressReport 96 }; 97 98 void didReceiveHeaders(const ContentSecurityPolicyResponseHeaders&); 99 void didReceiveHeader(const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource); 100 101 // These functions are wrong because they assume that there is only one header. 102 // FIXME: Replace them with functions that return vectors. 103 const String& deprecatedHeader() const; 104 ContentSecurityPolicyHeaderType deprecatedHeaderType() const; 105 106 bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const; 107 bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const; 108 bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const; 109 bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const; 110 bool allowEval(ScriptState* = 0, ReportingStatus = SendReport) const; 111 bool allowPluginType(const String& type, const String& typeAttribute, const KURL&, ReportingStatus = SendReport) const; 112 113 bool allowScriptFromSource(const KURL&, ReportingStatus = SendReport) const; 114 bool allowObjectFromSource(const KURL&, ReportingStatus = SendReport) const; 115 bool allowChildFrameFromSource(const KURL&, ReportingStatus = SendReport) const; 116 bool allowImageFromSource(const KURL&, ReportingStatus = SendReport) const; 117 bool allowStyleFromSource(const KURL&, ReportingStatus = SendReport) const; 118 bool allowFontFromSource(const KURL&, ReportingStatus = SendReport) const; 119 bool allowMediaFromSource(const KURL&, ReportingStatus = SendReport) const; 120 bool allowConnectToSource(const KURL&, ReportingStatus = SendReport) const; 121 bool allowFormAction(const KURL&, ReportingStatus = SendReport) const; 122 bool allowBaseURI(const KURL&, ReportingStatus = SendReport) const; 123 bool allowAncestors(LocalFrame*, ReportingStatus = SendReport) const; 124 bool allowChildContextFromSource(const KURL&, ReportingStatus = SendReport) const; 125 bool allowWorkerContextFromSource(const KURL&, ReportingStatus = SendReport) const; 126 127 // The nonce and hash allow functions are guaranteed to not have any side 128 // effects, including reporting. 129 bool allowScriptNonce(const String& nonce) const; 130 bool allowStyleNonce(const String& nonce) const; 131 bool allowScriptHash(const String& source) const; 132 bool allowStyleHash(const String& source) const; 133 134 void usesScriptHashAlgorithms(uint8_t ContentSecurityPolicyHashAlgorithm); 135 void usesStyleHashAlgorithms(uint8_t ContentSecurityPolicyHashAlgorithm); 136 137 ReflectedXSSDisposition reflectedXSSDisposition() const; 138 139 ReferrerPolicy referrerPolicy() const; 140 bool didSetReferrerPolicy() const; 141 142 void setOverrideAllowInlineStyle(bool); 143 144 bool isActive() const; 145 146 void reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression) const; 147 void reportDuplicateDirective(const String&) const; 148 void reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const; 149 void reportInvalidPathCharacter(const String& directiveName, const String& value, const char) const; 150 void reportInvalidPluginTypes(const String&) const; 151 void reportInvalidSandboxFlags(const String&) const; 152 void reportInvalidSourceExpression(const String& directiveName, const String& source) const; 153 void reportInvalidReflectedXSS(const String&) const; 154 void reportMissingReportURI(const String&) const; 155 void reportUnsupportedDirective(const String&) const; 156 void reportInvalidInReportOnly(const String&) const; 157 void reportInvalidReferrer(const String&) const; 158 void reportReportOnlyInMeta(const String&) const; 159 void reportMetaOutsideHead(const String&) const; 160 void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const Vector<KURL>& reportURIs, const String& header); 161 162 void reportBlockedScriptExecutionToInspector(const String& directiveText) const; 163 164 const KURL url() const; 165 KURL completeURL(const String&) const; 166 SecurityOrigin* securityOrigin() const; 167 void enforceSandboxFlags(SandboxFlags) const; 168 String evalDisabledErrorMessage() const; 169 170 bool experimentalFeaturesEnabled() const; 171 172 static bool shouldBypassMainWorld(ExecutionContext*); 173 174 static bool isDirectiveName(const String&); 175 executionContext()176 ExecutionContext* executionContext() const { return m_executionContext; } document()177 Document* document() const { return m_executionContext->isDocument() ? toDocument(m_executionContext) : 0; } 178 179 private: 180 explicit ContentSecurityPolicy(ExecutionContext*); 181 182 void logToConsole(const String& message) const; 183 void addPolicyFromHeaderValue(const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource); 184 185 bool shouldSendViolationReport(const String&) const; 186 void didSendViolationReport(const String&); 187 188 ExecutionContext* m_executionContext; 189 bool m_overrideInlineStyleAllowed; 190 CSPDirectiveListVector m_policies; 191 192 HashSet<unsigned, AlreadyHashed> m_violationReportsSent; 193 194 // We put the hash functions used on the policy object so that we only need 195 // to calculate a hash once and then distribute it to all of the directives 196 // for validation. 197 uint8_t m_scriptHashAlgorithmsUsed; 198 uint8_t m_styleHashAlgorithmsUsed; 199 }; 200 201 } 202 203 #endif 204