1/* 2 * Copyright (C) 2012 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#include "config.h" 27#include "DOMSecurityPolicy.h" 28 29#include "ContentSecurityPolicy.h" 30#include "ContextDestructionObserver.h" 31#include "DOMStringList.h" 32#include "Frame.h" 33#include "ScriptCallStack.h" 34#include "ScriptExecutionContext.h" 35#include <wtf/text/TextPosition.h> 36#include <wtf/text/WTFString.h> 37 38namespace WebCore { 39 40namespace { 41 42bool isPolicyActiveInContext(ScriptExecutionContext* context) 43{ 44 // If the ScriptExecutionContext has been destroyed, there's no active policy. 45 if (!context) 46 return false; 47 48 return context->contentSecurityPolicy()->isActive(); 49} 50 51template<bool (ContentSecurityPolicy::*allowWithType)(const String&, const String&, const KURL&, ContentSecurityPolicy::ReportingStatus) const> 52bool isAllowedWithType(ScriptExecutionContext* context, const String& type) 53{ 54 if (!isPolicyActiveInContext(context)) 55 return true; 56 57 return (context->contentSecurityPolicy()->*allowWithType)(type, type, KURL(), ContentSecurityPolicy::SuppressReport); 58} 59 60template<bool (ContentSecurityPolicy::*allowWithURL)(const KURL&, ContentSecurityPolicy::ReportingStatus) const> 61bool isAllowedWithURL(ScriptExecutionContext* context, const String& url) 62{ 63 if (!isPolicyActiveInContext(context)) 64 return true; 65 66 KURL parsedURL = context->completeURL(url); 67 if (!parsedURL.isValid()) 68 return false; // FIXME: Figure out how to throw a JavaScript error. 69 70 return (context->contentSecurityPolicy()->*allowWithURL)(parsedURL, ContentSecurityPolicy::SuppressReport); 71} 72 73template<bool (ContentSecurityPolicy::*allowWithContext)(const String&, const WTF::OrdinalNumber&, ContentSecurityPolicy::ReportingStatus) const> 74bool isAllowed(ScriptExecutionContext* context) 75{ 76 if (!isPolicyActiveInContext(context)) 77 return true; 78 79 return (context->contentSecurityPolicy()->*allowWithContext)(String(), WTF::OrdinalNumber::beforeFirst(), ContentSecurityPolicy::SuppressReport); 80} 81 82} // namespace 83 84DOMSecurityPolicy::DOMSecurityPolicy(ScriptExecutionContext* context) 85 : ContextDestructionObserver(context) 86{ 87} 88 89DOMSecurityPolicy::~DOMSecurityPolicy() 90{ 91} 92 93bool DOMSecurityPolicy::isActive() const 94{ 95 return isPolicyActiveInContext(scriptExecutionContext()); 96} 97 98PassRefPtr<DOMStringList> DOMSecurityPolicy::reportURIs() const 99{ 100 RefPtr<DOMStringList> result = DOMStringList::create(); 101 102 if (isActive()) 103 scriptExecutionContext()->contentSecurityPolicy()->gatherReportURIs(*result.get()); 104 105 return result.release(); 106} 107 108bool DOMSecurityPolicy::allowsInlineScript() const 109{ 110 return isAllowed<&ContentSecurityPolicy::allowInlineScript>(scriptExecutionContext()); 111} 112 113bool DOMSecurityPolicy::allowsInlineStyle() const 114{ 115 return isAllowed<&ContentSecurityPolicy::allowInlineStyle>(scriptExecutionContext()); 116} 117 118bool DOMSecurityPolicy::allowsEval() const 119{ 120 if (!isActive()) 121 return true; 122 123 return scriptExecutionContext()->contentSecurityPolicy()->allowEval(0, ContentSecurityPolicy::SuppressReport); 124} 125 126 127bool DOMSecurityPolicy::allowsConnectionTo(const String& url) const 128{ 129 return isAllowedWithURL<&ContentSecurityPolicy::allowConnectToSource>(scriptExecutionContext(), url); 130} 131 132bool DOMSecurityPolicy::allowsFontFrom(const String& url) const 133{ 134 return isAllowedWithURL<&ContentSecurityPolicy::allowFontFromSource>(scriptExecutionContext(), url); 135} 136 137bool DOMSecurityPolicy::allowsFormAction(const String& url) const 138{ 139 return isAllowedWithURL<&ContentSecurityPolicy::allowFormAction>(scriptExecutionContext(), url); 140} 141 142bool DOMSecurityPolicy::allowsFrameFrom(const String& url) const 143{ 144 return isAllowedWithURL<&ContentSecurityPolicy::allowChildFrameFromSource>(scriptExecutionContext(), url); 145} 146 147bool DOMSecurityPolicy::allowsImageFrom(const String& url) const 148{ 149 return isAllowedWithURL<&ContentSecurityPolicy::allowImageFromSource>(scriptExecutionContext(), url); 150} 151 152bool DOMSecurityPolicy::allowsMediaFrom(const String& url) const 153{ 154 return isAllowedWithURL<&ContentSecurityPolicy::allowMediaFromSource>(scriptExecutionContext(), url); 155} 156 157bool DOMSecurityPolicy::allowsObjectFrom(const String& url) const 158{ 159 return isAllowedWithURL<&ContentSecurityPolicy::allowObjectFromSource>(scriptExecutionContext(), url); 160} 161 162bool DOMSecurityPolicy::allowsPluginType(const String& type) const 163{ 164 return isAllowedWithType<&ContentSecurityPolicy::allowPluginType>(scriptExecutionContext(), type); 165} 166 167bool DOMSecurityPolicy::allowsScriptFrom(const String& url) const 168{ 169 return isAllowedWithURL<&ContentSecurityPolicy::allowScriptFromSource>(scriptExecutionContext(), url); 170} 171 172bool DOMSecurityPolicy::allowsStyleFrom(const String& url) const 173{ 174 return isAllowedWithURL<&ContentSecurityPolicy::allowStyleFromSource>(scriptExecutionContext(), url); 175} 176 177} // namespace WebCore 178