1/*
2 * Copyright (C) 2016 Igalia S.L.
3 * Copyright (C) 2017 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 APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28#include "WTFStringUtilities.h"
29#include <WebCore/SecurityOrigin.h>
30#include <wtf/FileSystem.h>
31#include <wtf/MainThread.h>
32#include <wtf/URL.h>
33
34using namespace WebCore;
35
36namespace TestWebKitAPI {
37
38class SecurityOriginTest : public testing::Test {
39public:
40 void SetUp() final {
41 WTF::initializeMainThread();
42
43 // create temp file
44 FileSystem::PlatformFileHandle handle;
45 m_tempFilePath = FileSystem::openTemporaryFile("tempTestFile", handle);
46 FileSystem::closeFile(handle);
47
48 m_spaceContainingFilePath = FileSystem::openTemporaryFile("temp Empty Test File", handle);
49 FileSystem::closeFile(handle);
50
51 m_bangContainingFilePath = FileSystem::openTemporaryFile("temp!Empty!Test!File", handle);
52 FileSystem::closeFile(handle);
53
54 m_quoteContainingFilePath = FileSystem::openTemporaryFile("temp\"Empty\"TestFile", handle);
55 FileSystem::closeFile(handle);
56 }
57
58 void TearDown() override
59 {
60 FileSystem::deleteFile(m_tempFilePath);
61 FileSystem::deleteFile(m_spaceContainingFilePath);
62 FileSystem::deleteFile(m_bangContainingFilePath);
63 FileSystem::deleteFile(m_quoteContainingFilePath);
64 }
65
66 const String& tempFilePath() { return m_tempFilePath; }
67 const String& spaceContainingFilePath() { return m_spaceContainingFilePath; }
68 const String& bangContainingFilePath() { return m_bangContainingFilePath; }
69 const String& quoteContainingFilePath() { return m_quoteContainingFilePath; }
70
71private:
72 String m_tempFilePath;
73 String m_spaceContainingFilePath;
74 String m_bangContainingFilePath;
75 String m_quoteContainingFilePath;
76};
77
78TEST_F(SecurityOriginTest, SecurityOriginConstructors)
79{
80 Ref<SecurityOrigin> o1 = SecurityOrigin::create("http", "example.com", Optional<uint16_t>(80));
81 Ref<SecurityOrigin> o2 = SecurityOrigin::create("http", "example.com", Optional<uint16_t>());
82 Ref<SecurityOrigin> o3 = SecurityOrigin::createFromString("http://example.com");
83 Ref<SecurityOrigin> o4 = SecurityOrigin::createFromString("http://example.com:80");
84 Ref<SecurityOrigin> o5 = SecurityOrigin::create(URL(URL(), "http://example.com"));
85 Ref<SecurityOrigin> o6 = SecurityOrigin::create(URL(URL(), "http://example.com:80"));
86
87 EXPECT_EQ(String("http"), o1->protocol());
88 EXPECT_EQ(String("http"), o2->protocol());
89 EXPECT_EQ(String("http"), o3->protocol());
90 EXPECT_EQ(String("http"), o4->protocol());
91 EXPECT_EQ(String("http"), o5->protocol());
92 EXPECT_EQ(String("http"), o6->protocol());
93
94 EXPECT_EQ(String("example.com"), o1->host());
95 EXPECT_EQ(String("example.com"), o2->host());
96 EXPECT_EQ(String("example.com"), o3->host());
97 EXPECT_EQ(String("example.com"), o4->host());
98 EXPECT_EQ(String("example.com"), o5->host());
99 EXPECT_EQ(String("example.com"), o6->host());
100
101 EXPECT_FALSE(o1->port());
102 EXPECT_FALSE(o2->port());
103 EXPECT_FALSE(o3->port());
104 EXPECT_FALSE(o4->port());
105 EXPECT_FALSE(o5->port());
106 EXPECT_FALSE(o6->port());
107
108 EXPECT_EQ("http://example.com", o1->toString());
109 EXPECT_EQ("http://example.com", o2->toString());
110 EXPECT_EQ("http://example.com", o3->toString());
111 EXPECT_EQ("http://example.com", o4->toString());
112 EXPECT_EQ("http://example.com", o5->toString());
113 EXPECT_EQ("http://example.com", o6->toString());
114
115 EXPECT_TRUE(o1->isSameOriginAs(o2.get()));
116 EXPECT_TRUE(o1->isSameOriginAs(o3.get()));
117 EXPECT_TRUE(o1->isSameOriginAs(o4.get()));
118 EXPECT_TRUE(o1->isSameOriginAs(o5.get()));
119 EXPECT_TRUE(o1->isSameOriginAs(o6.get()));
120}
121
122TEST_F(SecurityOriginTest, SecurityOriginFileBasedConstructors)
123{
124 auto tempFileOrigin = SecurityOrigin::create(URL(URL(), "file:///" + tempFilePath()));
125 auto spaceContainingOrigin = SecurityOrigin::create(URL(URL(), "file:///" + spaceContainingFilePath()));
126 auto bangContainingOrigin = SecurityOrigin::create(URL(URL(), "file:///" + bangContainingFilePath()));
127 auto quoteContainingOrigin = SecurityOrigin::create(URL(URL(), "file:///" + quoteContainingFilePath()));
128
129 EXPECT_EQ(String("file"), tempFileOrigin->protocol());
130 EXPECT_EQ(String("file"), spaceContainingOrigin->protocol());
131 EXPECT_EQ(String("file"), bangContainingOrigin->protocol());
132 EXPECT_EQ(String("file"), quoteContainingOrigin->protocol());
133
134 EXPECT_TRUE(tempFileOrigin->isSameOriginAs(spaceContainingOrigin.get()));
135 EXPECT_TRUE(tempFileOrigin->isSameOriginAs(bangContainingOrigin.get()));
136 EXPECT_TRUE(tempFileOrigin->isSameOriginAs(quoteContainingOrigin.get()));
137
138 EXPECT_TRUE(tempFileOrigin->isSameSchemeHostPort(spaceContainingOrigin.get()));
139 EXPECT_TRUE(tempFileOrigin->isSameSchemeHostPort(bangContainingOrigin.get()));
140 EXPECT_TRUE(tempFileOrigin->isSameSchemeHostPort(quoteContainingOrigin.get()));
141
142 EXPECT_TRUE(tempFileOrigin->canAccess(spaceContainingOrigin.get()));
143 EXPECT_TRUE(tempFileOrigin->canAccess(bangContainingOrigin.get()));
144 EXPECT_TRUE(tempFileOrigin->canAccess(quoteContainingOrigin.get()));
145}
146
147TEST_F(SecurityOriginTest, IsPotentiallyTrustworthy)
148{
149 // Potentially Trustworthy
150 EXPECT_TRUE(SecurityOrigin::create(URL(URL(), "file:///" + tempFilePath()))->isPotentiallyTrustworthy());
151 EXPECT_TRUE(SecurityOrigin::createFromString("blob:http://127.0.0.1/3D45F36F-C126-493A-A8AA-457FA495247B")->isPotentiallyTrustworthy());
152 EXPECT_TRUE(SecurityOrigin::createFromString("blob:http://localhost/3D45F36F-C126-493A-A8AA-457FA495247B")->isPotentiallyTrustworthy());
153 EXPECT_TRUE(SecurityOrigin::createFromString("blob:http://[::1]/3D45F36F-C126-493A-A8AA-457FA495247B")->isPotentiallyTrustworthy());
154 EXPECT_TRUE(SecurityOrigin::createFromString("blob:https://example.com/3D45F36F-C126-493A-A8AA-457FA495247B")->isPotentiallyTrustworthy());
155 EXPECT_TRUE(SecurityOrigin::createFromString("data:,a")->isPotentiallyTrustworthy());
156 EXPECT_TRUE(SecurityOrigin::createFromString("about:")->isPotentiallyTrustworthy());
157 EXPECT_TRUE(SecurityOrigin::createFromString("about:blank")->isPotentiallyTrustworthy());
158 EXPECT_TRUE(SecurityOrigin::createFromString("about:srcdoc")->isPotentiallyTrustworthy());
159 EXPECT_TRUE(SecurityOrigin::createFromString("wss://example.com")->isPotentiallyTrustworthy());
160 EXPECT_TRUE(SecurityOrigin::createFromString("https://example.com")->isPotentiallyTrustworthy());
161 EXPECT_TRUE(SecurityOrigin::createFromString("http://127.0.0.0")->isPotentiallyTrustworthy());
162 EXPECT_TRUE(SecurityOrigin::createFromString("http://127.0.0.1")->isPotentiallyTrustworthy());
163 EXPECT_TRUE(SecurityOrigin::createFromString("http://127.0.0.2")->isPotentiallyTrustworthy());
164 EXPECT_TRUE(SecurityOrigin::createFromString("http://127.0.1.1")->isPotentiallyTrustworthy());
165 EXPECT_TRUE(SecurityOrigin::createFromString("http://127.1.1.1")->isPotentiallyTrustworthy());
166 EXPECT_TRUE(SecurityOrigin::createFromString("http://localhost")->isPotentiallyTrustworthy());
167 EXPECT_TRUE(SecurityOrigin::createFromString("http://loCALhoST")->isPotentiallyTrustworthy());
168 EXPECT_TRUE(SecurityOrigin::createFromString("http://[::1]")->isPotentiallyTrustworthy());
169#if PLATFORM(COCOA)
170 EXPECT_TRUE(SecurityOrigin::createFromString("applewebdata:a")->isPotentiallyTrustworthy());
171#endif
172#if PLATFORM(GTK) || PLATFORM(WPE)
173 EXPECT_TRUE(SecurityOrigin::createFromString("resource:a")->isPotentiallyTrustworthy());
174#endif
175
176 // Not Trustworthy
177 EXPECT_FALSE(SecurityOrigin::createFromString("http:/malformed")->isPotentiallyTrustworthy());
178 EXPECT_FALSE(SecurityOrigin::createFromString("http://example.com")->isPotentiallyTrustworthy());
179 EXPECT_FALSE(SecurityOrigin::createFromString("http://31.13.77.36")->isPotentiallyTrustworthy());
180 EXPECT_FALSE(SecurityOrigin::createFromString("http://[2a03:2880:f10d:83:face:b00c::25de]")->isPotentiallyTrustworthy());
181 EXPECT_FALSE(SecurityOrigin::createFromString("ws://example.com")->isPotentiallyTrustworthy());
182 EXPECT_FALSE(SecurityOrigin::createFromString("blob:http://example.com/3D45F36F-C126-493A-A8AA-457FA495247B")->isPotentiallyTrustworthy());
183 EXPECT_FALSE(SecurityOrigin::createFromString("dummy:a")->isPotentiallyTrustworthy());
184}
185
186TEST_F(SecurityOriginTest, IsRegistrableDomainSuffix)
187{
188 auto exampleOrigin = SecurityOrigin::create(URL(URL(), "http://www.example.com"));
189 EXPECT_TRUE(exampleOrigin->isMatchingRegistrableDomainSuffix("example.com"));
190 EXPECT_TRUE(exampleOrigin->isMatchingRegistrableDomainSuffix("www.example.com"));
191#if !ENABLE(PUBLIC_SUFFIX_LIST)
192 EXPECT_TRUE(exampleOrigin->isMatchingRegistrableDomainSuffix("com"));
193#endif
194 EXPECT_FALSE(exampleOrigin->isMatchingRegistrableDomainSuffix(""));
195 EXPECT_FALSE(exampleOrigin->isMatchingRegistrableDomainSuffix("."));
196 EXPECT_FALSE(exampleOrigin->isMatchingRegistrableDomainSuffix(".example.com"));
197 EXPECT_FALSE(exampleOrigin->isMatchingRegistrableDomainSuffix(".www.example.com"));
198 EXPECT_FALSE(exampleOrigin->isMatchingRegistrableDomainSuffix("example.com."));
199#if ENABLE(PUBLIC_SUFFIX_LIST)
200 EXPECT_FALSE(exampleOrigin->isMatchingRegistrableDomainSuffix("com"));
201#endif
202
203 auto exampleDotOrigin = SecurityOrigin::create(URL(URL(), "http://www.example.com."));
204 EXPECT_TRUE(exampleDotOrigin->isMatchingRegistrableDomainSuffix("example.com."));
205 EXPECT_TRUE(exampleDotOrigin->isMatchingRegistrableDomainSuffix("www.example.com."));
206#if !ENABLE(PUBLIC_SUFFIX_LIST)
207 EXPECT_TRUE(exampleOrigin->isMatchingRegistrableDomainSuffix("com."));
208#endif
209 EXPECT_FALSE(exampleDotOrigin->isMatchingRegistrableDomainSuffix(""));
210 EXPECT_FALSE(exampleDotOrigin->isMatchingRegistrableDomainSuffix("."));
211 EXPECT_FALSE(exampleDotOrigin->isMatchingRegistrableDomainSuffix(".example.com."));
212 EXPECT_FALSE(exampleDotOrigin->isMatchingRegistrableDomainSuffix(".www.example.com."));
213 EXPECT_FALSE(exampleDotOrigin->isMatchingRegistrableDomainSuffix("example.com"));
214#if ENABLE(PUBLIC_SUFFIX_LIST)
215 EXPECT_FALSE(exampleDotOrigin->isMatchingRegistrableDomainSuffix("com"));
216#endif
217
218 auto ipOrigin = SecurityOrigin::create(URL(URL(), "http://127.0.0.1"));
219 EXPECT_TRUE(ipOrigin->isMatchingRegistrableDomainSuffix("127.0.0.1", true));
220 EXPECT_FALSE(ipOrigin->isMatchingRegistrableDomainSuffix("127.0.0.2", true));
221
222 auto comOrigin = SecurityOrigin::create(URL(URL(), "http://com"));
223 EXPECT_TRUE(comOrigin->isMatchingRegistrableDomainSuffix("com"));
224}
225
226} // namespace TestWebKitAPI
227