diff options
author | ArthurHoaro <arthur@hoa.ro> | 2020-09-22 15:17:13 +0200 |
---|---|---|
committer | ArthurHoaro <arthur@hoa.ro> | 2020-09-22 15:37:26 +0200 |
commit | abe033be855f76fde9e8576ce36460fbb23b1e57 (patch) | |
tree | eefc804a0cb8c0497a03c954667fd3e75598d0aa | |
parent | 5baafe5001ef2fbe88d3fcdcc225ec12edd3fef1 (diff) | |
download | Shaarli-abe033be855f76fde9e8576ce36460fbb23b1e57.tar.gz Shaarli-abe033be855f76fde9e8576ce36460fbb23b1e57.tar.zst Shaarli-abe033be855f76fde9e8576ce36460fbb23b1e57.zip |
Fix invalid redirection using the path of an external domain
Fixes #1554
5 files changed, 54 insertions, 16 deletions
diff --git a/application/front/controller/visitor/ShaarliVisitorController.php b/application/front/controller/visitor/ShaarliVisitorController.php index cd27455b..55c075a2 100644 --- a/application/front/controller/visitor/ShaarliVisitorController.php +++ b/application/front/controller/visitor/ShaarliVisitorController.php | |||
@@ -142,6 +142,13 @@ abstract class ShaarliVisitorController | |||
142 | 142 | ||
143 | if (null !== $referer) { | 143 | if (null !== $referer) { |
144 | $currentUrl = parse_url($referer); | 144 | $currentUrl = parse_url($referer); |
145 | // If the referer is not related to Shaarli instance, redirect to default | ||
146 | if (isset($currentUrl['host']) | ||
147 | && strpos(index_url($this->container->environment), $currentUrl['host']) === false | ||
148 | ) { | ||
149 | return $response->withRedirect($defaultPath); | ||
150 | } | ||
151 | |||
145 | parse_str($currentUrl['query'] ?? '', $params); | 152 | parse_str($currentUrl['query'] ?? '', $params); |
146 | $path = $currentUrl['path'] ?? $defaultPath; | 153 | $path = $currentUrl['path'] ?? $defaultPath; |
147 | } else { | 154 | } else { |
diff --git a/tests/front/controller/admin/ManageShaareControllerTest/SaveBookmarkTest.php b/tests/front/controller/admin/ManageShaareControllerTest/SaveBookmarkTest.php index dabcd60d..58eaaa9b 100644 --- a/tests/front/controller/admin/ManageShaareControllerTest/SaveBookmarkTest.php +++ b/tests/front/controller/admin/ManageShaareControllerTest/SaveBookmarkTest.php | |||
@@ -43,7 +43,7 @@ class SaveBookmarkTest extends TestCase | |||
43 | 'lf_description' => 'Provided description.', | 43 | 'lf_description' => 'Provided description.', |
44 | 'lf_tags' => 'abc def', | 44 | 'lf_tags' => 'abc def', |
45 | 'lf_private' => '1', | 45 | 'lf_private' => '1', |
46 | 'returnurl' => 'http://shaarli.tld/subfolder/admin/add-shaare' | 46 | 'returnurl' => 'http://shaarli/subfolder/admin/add-shaare' |
47 | ]; | 47 | ]; |
48 | 48 | ||
49 | $request = $this->createMock(Request::class); | 49 | $request = $this->createMock(Request::class); |
@@ -124,7 +124,7 @@ class SaveBookmarkTest extends TestCase | |||
124 | 'lf_description' => 'Provided description.', | 124 | 'lf_description' => 'Provided description.', |
125 | 'lf_tags' => 'abc def', | 125 | 'lf_tags' => 'abc def', |
126 | 'lf_private' => '1', | 126 | 'lf_private' => '1', |
127 | 'returnurl' => 'http://shaarli.tld/subfolder/?page=2' | 127 | 'returnurl' => 'http://shaarli/subfolder/?page=2' |
128 | ]; | 128 | ]; |
129 | 129 | ||
130 | $request = $this->createMock(Request::class); | 130 | $request = $this->createMock(Request::class); |
diff --git a/tests/front/controller/admin/SessionFilterControllerTest.php b/tests/front/controller/admin/SessionFilterControllerTest.php index d306c6e9..c4253167 100644 --- a/tests/front/controller/admin/SessionFilterControllerTest.php +++ b/tests/front/controller/admin/SessionFilterControllerTest.php | |||
@@ -31,7 +31,7 @@ class SessionFilterControllerTest extends TestCase | |||
31 | { | 31 | { |
32 | $arg = ['visibility' => 'private']; | 32 | $arg = ['visibility' => 'private']; |
33 | 33 | ||
34 | $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; | 34 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller/?searchtag=abc'; |
35 | 35 | ||
36 | $this->container->loginManager->method('isLoggedIn')->willReturn(true); | 36 | $this->container->loginManager->method('isLoggedIn')->willReturn(true); |
37 | $this->container->sessionManager | 37 | $this->container->sessionManager |
@@ -57,7 +57,7 @@ class SessionFilterControllerTest extends TestCase | |||
57 | { | 57 | { |
58 | $arg = ['visibility' => 'private']; | 58 | $arg = ['visibility' => 'private']; |
59 | 59 | ||
60 | $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; | 60 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller/?searchtag=abc'; |
61 | 61 | ||
62 | $this->container->loginManager->method('isLoggedIn')->willReturn(true); | 62 | $this->container->loginManager->method('isLoggedIn')->willReturn(true); |
63 | $this->container->sessionManager | 63 | $this->container->sessionManager |
@@ -121,7 +121,7 @@ class SessionFilterControllerTest extends TestCase | |||
121 | { | 121 | { |
122 | $arg = ['visibility' => 'test']; | 122 | $arg = ['visibility' => 'test']; |
123 | 123 | ||
124 | $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; | 124 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller/?searchtag=abc'; |
125 | 125 | ||
126 | $this->container->loginManager->method('isLoggedIn')->willReturn(true); | 126 | $this->container->loginManager->method('isLoggedIn')->willReturn(true); |
127 | $this->container->sessionManager | 127 | $this->container->sessionManager |
@@ -151,7 +151,7 @@ class SessionFilterControllerTest extends TestCase | |||
151 | { | 151 | { |
152 | $arg = ['visibility' => 'test']; | 152 | $arg = ['visibility' => 'test']; |
153 | 153 | ||
154 | $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; | 154 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller/?searchtag=abc'; |
155 | 155 | ||
156 | $this->container->loginManager = $this->createMock(LoginManager::class); | 156 | $this->container->loginManager = $this->createMock(LoginManager::class); |
157 | $this->container->loginManager->method('isLoggedIn')->willReturn(false); | 157 | $this->container->loginManager->method('isLoggedIn')->willReturn(false); |
diff --git a/tests/front/controller/visitor/PublicSessionFilterControllerTest.php b/tests/front/controller/visitor/PublicSessionFilterControllerTest.php index 06352750..b45fbe53 100644 --- a/tests/front/controller/visitor/PublicSessionFilterControllerTest.php +++ b/tests/front/controller/visitor/PublicSessionFilterControllerTest.php | |||
@@ -28,7 +28,7 @@ class PublicSessionFilterControllerTest extends TestCase | |||
28 | */ | 28 | */ |
29 | public function testLinksPerPage(): void | 29 | public function testLinksPerPage(): void |
30 | { | 30 | { |
31 | $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; | 31 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller/?searchtag=abc'; |
32 | 32 | ||
33 | $request = $this->createMock(Request::class); | 33 | $request = $this->createMock(Request::class); |
34 | $request->method('getParam')->with('nb')->willReturn('8'); | 34 | $request->method('getParam')->with('nb')->willReturn('8'); |
@@ -74,7 +74,7 @@ class PublicSessionFilterControllerTest extends TestCase | |||
74 | */ | 74 | */ |
75 | public function testUntaggedOnly(): void | 75 | public function testUntaggedOnly(): void |
76 | { | 76 | { |
77 | $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; | 77 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller/?searchtag=abc'; |
78 | 78 | ||
79 | $request = $this->createMock(Request::class); | 79 | $request = $this->createMock(Request::class); |
80 | $response = new Response(); | 80 | $response = new Response(); |
@@ -97,7 +97,7 @@ class PublicSessionFilterControllerTest extends TestCase | |||
97 | */ | 97 | */ |
98 | public function testUntaggedOnlyToggleOff(): void | 98 | public function testUntaggedOnlyToggleOff(): void |
99 | { | 99 | { |
100 | $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; | 100 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller/?searchtag=abc'; |
101 | 101 | ||
102 | $request = $this->createMock(Request::class); | 102 | $request = $this->createMock(Request::class); |
103 | $response = new Response(); | 103 | $response = new Response(); |
diff --git a/tests/front/controller/visitor/ShaarliVisitorControllerTest.php b/tests/front/controller/visitor/ShaarliVisitorControllerTest.php index 316ce49c..00188c02 100644 --- a/tests/front/controller/visitor/ShaarliVisitorControllerTest.php +++ b/tests/front/controller/visitor/ShaarliVisitorControllerTest.php | |||
@@ -110,7 +110,7 @@ class ShaarliVisitorControllerTest extends TestCase | |||
110 | */ | 110 | */ |
111 | public function testRedirectFromRefererDefault(): void | 111 | public function testRedirectFromRefererDefault(): void |
112 | { | 112 | { |
113 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli.tld/subfolder/controller?query=param&other=2'; | 113 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller?query=param&other=2'; |
114 | 114 | ||
115 | $response = new Response(); | 115 | $response = new Response(); |
116 | 116 | ||
@@ -125,7 +125,7 @@ class ShaarliVisitorControllerTest extends TestCase | |||
125 | */ | 125 | */ |
126 | public function testRedirectFromRefererWithUnmatchedLoopTerm(): void | 126 | public function testRedirectFromRefererWithUnmatchedLoopTerm(): void |
127 | { | 127 | { |
128 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli.tld/subfolder/controller?query=param&other=2'; | 128 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller?query=param&other=2'; |
129 | 129 | ||
130 | $response = new Response(); | 130 | $response = new Response(); |
131 | 131 | ||
@@ -140,7 +140,7 @@ class ShaarliVisitorControllerTest extends TestCase | |||
140 | */ | 140 | */ |
141 | public function testRedirectFromRefererWithMatchingLoopTermInPath(): void | 141 | public function testRedirectFromRefererWithMatchingLoopTermInPath(): void |
142 | { | 142 | { |
143 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli.tld/subfolder/controller?query=param&other=2'; | 143 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller?query=param&other=2'; |
144 | 144 | ||
145 | $response = new Response(); | 145 | $response = new Response(); |
146 | 146 | ||
@@ -155,7 +155,7 @@ class ShaarliVisitorControllerTest extends TestCase | |||
155 | */ | 155 | */ |
156 | public function testRedirectFromRefererWithMatchingLoopTermInQueryParam(): void | 156 | public function testRedirectFromRefererWithMatchingLoopTermInQueryParam(): void |
157 | { | 157 | { |
158 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli.tld/subfolder/controller?query=param&other=2'; | 158 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller?query=param&other=2'; |
159 | 159 | ||
160 | $response = new Response(); | 160 | $response = new Response(); |
161 | 161 | ||
@@ -171,7 +171,7 @@ class ShaarliVisitorControllerTest extends TestCase | |||
171 | */ | 171 | */ |
172 | public function testRedirectFromRefererWithMatchingLoopTermInQueryValue(): void | 172 | public function testRedirectFromRefererWithMatchingLoopTermInQueryValue(): void |
173 | { | 173 | { |
174 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli.tld/subfolder/controller?query=param&other=2'; | 174 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller?query=param&other=2'; |
175 | 175 | ||
176 | $response = new Response(); | 176 | $response = new Response(); |
177 | 177 | ||
@@ -187,7 +187,7 @@ class ShaarliVisitorControllerTest extends TestCase | |||
187 | */ | 187 | */ |
188 | public function testRedirectFromRefererWithLoopTermInDomain(): void | 188 | public function testRedirectFromRefererWithLoopTermInDomain(): void |
189 | { | 189 | { |
190 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli.tld/subfolder/controller?query=param&other=2'; | 190 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller?query=param&other=2'; |
191 | 191 | ||
192 | $response = new Response(); | 192 | $response = new Response(); |
193 | 193 | ||
@@ -203,7 +203,7 @@ class ShaarliVisitorControllerTest extends TestCase | |||
203 | */ | 203 | */ |
204 | public function testRedirectFromRefererWithMatchingClearedParam(): void | 204 | public function testRedirectFromRefererWithMatchingClearedParam(): void |
205 | { | 205 | { |
206 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli.tld/subfolder/controller?query=param&other=2'; | 206 | $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller?query=param&other=2'; |
207 | 207 | ||
208 | $response = new Response(); | 208 | $response = new Response(); |
209 | 209 | ||
@@ -212,4 +212,35 @@ class ShaarliVisitorControllerTest extends TestCase | |||
212 | static::assertSame(302, $result->getStatusCode()); | 212 | static::assertSame(302, $result->getStatusCode()); |
213 | static::assertSame(['/subfolder/controller?other=2'], $result->getHeader('location')); | 213 | static::assertSame(['/subfolder/controller?other=2'], $result->getHeader('location')); |
214 | } | 214 | } |
215 | |||
216 | /** | ||
217 | * Test redirectFromReferer() - From another domain -> we ignore the given referrer. | ||
218 | */ | ||
219 | public function testRedirectExternalReferer(): void | ||
220 | { | ||
221 | $this->container->environment['HTTP_REFERER'] = 'http://other.domain.tld/controller?query=param&other=2'; | ||
222 | |||
223 | $response = new Response(); | ||
224 | |||
225 | $result = $this->controller->redirectFromReferer($this->request, $response, ['query'], ['query']); | ||
226 | |||
227 | static::assertSame(302, $result->getStatusCode()); | ||
228 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
229 | } | ||
230 | |||
231 | /** | ||
232 | * Test redirectFromReferer() - From another domain -> we ignore the given referrer. | ||
233 | */ | ||
234 | public function testRedirectExternalRefererExplicitDomainName(): void | ||
235 | { | ||
236 | $this->container->environment['SERVER_NAME'] = 'my.shaarli.tld'; | ||
237 | $this->container->environment['HTTP_REFERER'] = 'http://your.shaarli.tld/controller?query=param&other=2'; | ||
238 | |||
239 | $response = new Response(); | ||
240 | |||
241 | $result = $this->controller->redirectFromReferer($this->request, $response, ['query'], ['query']); | ||
242 | |||
243 | static::assertSame(302, $result->getStatusCode()); | ||
244 | static::assertSame(['/subfolder/'], $result->getHeader('location')); | ||
245 | } | ||
215 | } | 246 | } |