1 /*
2  * Copyright (C) 2007, 2008 Apple 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  *
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  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #ifndef SecurityOrigin_h
30 #define SecurityOrigin_h
31 
32 #include "FrameLoaderTypes.h"
33 #include "PlatformString.h"
34 #include <wtf/ThreadSafeRefCounted.h>
35 
36 namespace WebCore {
37 
38 class Document;
39 class KURL;
40 
41 class SecurityOrigin : public ThreadSafeRefCounted<SecurityOrigin> {
42 public:
43     static PassRefPtr<SecurityOrigin> createFromDatabaseIdentifier(const String&);
44     static PassRefPtr<SecurityOrigin> createFromString(const String&);
45     static PassRefPtr<SecurityOrigin> create(const String& protocol, const String& host, int port);
46     static PassRefPtr<SecurityOrigin> create(const KURL&, SandboxFlags = SandboxNone);
47     static PassRefPtr<SecurityOrigin> createEmpty();
48 
49     // Create a deep copy of this SecurityOrigin. This method is useful
50     // when marshalling a SecurityOrigin to another thread.
51     PassRefPtr<SecurityOrigin> threadsafeCopy();
52 
53     // Set the domain property of this security origin to newDomain. This
54     // function does not check whether newDomain is a suffix of the current
55     // domain. The caller is responsible for validating newDomain.
56     void setDomainFromDOM(const String& newDomain);
domainWasSetInDOM()57     bool domainWasSetInDOM() const { return m_domainWasSetInDOM; }
58 
59     static void setDomainRelaxationForbiddenForURLScheme(bool forbidden, const String&);
60     static bool isDomainRelaxationForbiddenForURLScheme(const String&);
61 
protocol()62     String protocol() const { return m_protocol; }
host()63     String host() const { return m_host; }
domain()64     String domain() const { return m_domain; }
port()65     unsigned short port() const { return m_port; }
66 
67     // Returns true if this SecurityOrigin can script objects in the given
68     // SecurityOrigin. For example, call this function before allowing
69     // script from one security origin to read or write objects from
70     // another SecurityOrigin.
71     bool canAccess(const SecurityOrigin*) const;
72 
73     // Returns true if this SecurityOrigin can read content retrieved from
74     // the given URL. For example, call this function before issuing
75     // XMLHttpRequests.
76     bool canRequest(const KURL&) const;
77 
78     // Returns true if drawing an image from this URL taints a canvas from
79     // this security origin. For example, call this function before
80     // drawing an image onto an HTML canvas element with the drawImage API.
81     bool taintsCanvas(const KURL&) const;
82 
83     // Returns true if this SecurityOrigin can receive drag content from the
84     // initiator. For example, call this function before allowing content to be
85     // dropped onto a target.
86     bool canReceiveDragData(const SecurityOrigin* dragInitiator) const;
87 
88     // Returns true if |document| can display content from the given URL (e.g.,
89     // in an iframe or as an image). For example, web sites generally cannot
90     // display content from the user's files system.
91     bool canDisplay(const KURL&) const;
92 
93     // Returns true if this SecurityOrigin can load local resources, such
94     // as images, iframes, and style sheets, and can link to local URLs.
95     // For example, call this function before creating an iframe to a
96     // file:// URL.
97     //
98     // Note: A SecurityOrigin might be allowed to load local resources
99     //       without being able to issue an XMLHttpRequest for a local URL.
100     //       To determine whether the SecurityOrigin can issue an
101     //       XMLHttpRequest for a URL, call canRequest(url).
canLoadLocalResources()102     bool canLoadLocalResources() const { return m_canLoadLocalResources; }
103 
104     // Explicitly grant the ability to load local resources to this
105     // SecurityOrigin.
106     //
107     // Note: This method exists only to support backwards compatibility
108     //       with older versions of WebKit.
109     void grantLoadLocalResources();
110 
111     // Explicitly grant the ability to access very other SecurityOrigin.
112     //
113     // WARNING: This is an extremely powerful ability. Use with caution!
114     void grantUniversalAccess();
115 
isSandboxed(SandboxFlags mask)116     bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; }
117 
canAccessDatabase()118     bool canAccessDatabase() const { return !isUnique(); }
canAccessLocalStorage()119     bool canAccessLocalStorage() const { return !isUnique(); }
canAccessCookies()120     bool canAccessCookies() const { return !isUnique(); }
canAccessPasswordManager()121     bool canAccessPasswordManager() const { return !isUnique(); }
canAccessFileSystem()122     bool canAccessFileSystem() const { return !isUnique(); }
123 
124     // Technically, we should always allow access to sessionStorage, but we
125     // currently don't handle creating a sessionStorage area for unique
126     // origins.
canAccessSessionStorage()127     bool canAccessSessionStorage() const { return !isUnique(); }
128 
129     bool isSecureTransitionTo(const KURL&) const;
130 
131     // The local SecurityOrigin is the most privileged SecurityOrigin.
132     // The local SecurityOrigin can script any document, navigate to local
133     // resources, and can set arbitrary headers on XMLHttpRequests.
134     bool isLocal() const;
135 
136     // The origin is a globally unique identifier assigned when the Document is
137     // created. http://www.whatwg.org/specs/web-apps/current-work/#sandboxOrigin
138     //
139     // There's a subtle difference between a unique origin and an origin that
140     // has the SandboxOrigin flag set. The latter implies the former, and, in
141     // addition, the SandboxOrigin flag is inherited by iframes.
isUnique()142     bool isUnique() const { return m_isUnique; }
143 
144     // The empty SecurityOrigin is a unique security orign (in the sense of
145     // isUnique above) that was created for a "blank" document, such about
146     // about:blank. Empty origins differ from unique origins in that they can
147     // sometimes be replaced by non-empty origins, for example when an
148     // about:blank iframe inherits its security origin from its parent frame.
149     bool isEmpty() const;
150 
151     // Marks a file:// origin as being in a domain defined by its path.
152     void enforceFilePathSeparation();
153 
154     // Convert this SecurityOrigin into a string. The string
155     // representation of a SecurityOrigin is similar to a URL, except it
156     // lacks a path component. The string representation does not encode
157     // the value of the SecurityOrigin's domain property.
158     //
159     // When using the string value, it's important to remember that it might be
160     // "null". This happens when this SecurityOrigin is unique. For example,
161     // this SecurityOrigin might have come from a sandboxed iframe, the
162     // SecurityOrigin might be empty, or we might have explicitly decided that
163     // we shouldTreatURLSchemeAsNoAccess.
164     String toString() const;
165 
166     // Serialize the security origin to a string that could be used as part of
167     // file names. This format should be used in storage APIs only.
168     String databaseIdentifier() const;
169 
170     // This method checks for equality between SecurityOrigins, not whether
171     // one origin can access another. It is used for hash table keys.
172     // For access checks, use canAccess().
173     // FIXME: If this method is really only useful for hash table keys, it
174     // should be refactored into SecurityOriginHash.
175     bool equal(const SecurityOrigin*) const;
176 
177     // This method checks for equality, ignoring the value of document.domain
178     // (and whether it was set) but considering the host. It is used for postMessage.
179     bool isSameSchemeHostPort(const SecurityOrigin*) const;
180 
181     static bool shouldHideReferrer(const KURL&, const String& referrer);
182 
183     enum LocalLoadPolicy {
184         AllowLocalLoadsForAll, // No restriction on local loads.
185         AllowLocalLoadsForLocalAndSubstituteData,
186         AllowLocalLoadsForLocalOnly,
187     };
188     static void setLocalLoadPolicy(LocalLoadPolicy);
189     static bool restrictAccessToLocal();
190     static bool allowSubstituteDataAccessToLocal();
191 
192     static void addOriginAccessWhitelistEntry(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomains, bool allowDestinationSubdomains);
193     static void removeOriginAccessWhitelistEntry(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomains, bool allowDestinationSubdomains);
194     static void resetOriginAccessWhitelists();
195 
196 private:
197     SecurityOrigin(const KURL&, SandboxFlags);
198     explicit SecurityOrigin(const SecurityOrigin*);
199 
200     // FIXME: Rename this function to something more semantic.
201     bool passesFileCheck(const SecurityOrigin*) const;
202 
203     bool isAccessWhiteListed(const SecurityOrigin*) const;
204     bool isAccessToURLWhiteListed(const KURL&) const;
205 
206     SandboxFlags m_sandboxFlags;
207     String m_protocol;
208     String m_host;
209     mutable String m_encodedHost;
210     String m_domain;
211     String m_filePath;
212     unsigned short m_port;
213     bool m_isUnique;
214     bool m_universalAccess;
215     bool m_domainWasSetInDOM;
216     bool m_canLoadLocalResources;
217     bool m_enforceFilePathSeparation;
218 };
219 
220 } // namespace WebCore
221 
222 #endif // SecurityOrigin_h
223