Skip to content

Commit d5f5bde

Browse files
Disallow external redirects
1 parent 24f1446 commit d5f5bde

File tree

7 files changed

+38
-12
lines changed

7 files changed

+38
-12
lines changed

MangAdventure/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""A simple manga hosting CMS written in Django."""
22

33
__license__ = 'MIT'
4-
__version__ = '0.9.3'
4+
__version__ = '0.9.4'
55
__author__ = 'evangelos-ch, ObserverOfTime'

config/urls.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
)
3232
if find_spec('debug_toolbar'):
3333
from debug_toolbar import urls as djdt_urls
34-
urlpatterns.append(path('__debug__/', include(djdt_urls)))
34+
urlpatterns.append(
35+
path('__debug__/', include(djdt_urls)) # type: ignore
36+
)
3537

3638
__all__ = ['urlpatterns']

docs/changelog.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
Changelog
22
---------
33

4+
v0.9.4
5+
^^^^^^
6+
7+
* Fixed error on invalid chapter redirect
8+
* Fixed external redirects being allowed
9+
410
v0.9.3
511
^^^^^^
612

docs/install.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Finally, install MangAdventure inside the activated virtualenv:
4141

4242
.. code-block:: bash
4343
44-
pip install -e "git+https://github.com/mangadventure/MangAdventure@v0.9.3#egg=mangadventure"
44+
pip install -e "git+https://github.com/mangadventure/MangAdventure@v0.9.4#egg=mangadventure"
4545
4646
MangAdventure also provides the following extras:
4747

@@ -55,7 +55,7 @@ For example, you can install ``csp`` & ``uwsgi`` like so:
5555

5656
.. code-block:: bash
5757
58-
pip install -e "git+https://github.com/mangadventure/MangAdventure@v0.9.3#egg=mangadventure[csp,uwsgi]"
58+
pip install -e "git+https://github.com/mangadventure/MangAdventure@v0.9.4#egg=mangadventure[csp,uwsgi]"
5959
6060
.. _MySQL database support:
6161
https://mysql.com/

reader/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ def __str__(self) -> str:
577577
"""
578578
# TODO: use removeprefix (Py3.9+)
579579
if not self.series: # pragma: no cover
580-
return Series.format.default.format(
580+
return Series.format.default.format( # type: ignore
581581
title=self.title or 'N/A',
582582
volume=self.volume or '?',
583583
number=f'{self.number:g}',

users/adapters.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from typing import TYPE_CHECKING
66

77
from allauth.account.adapter import DefaultAccountAdapter
8+
from allauth.account.utils import get_next_redirect_url
89
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
910

1011
if TYPE_CHECKING: # pragma: no cover
@@ -23,7 +24,7 @@ def get_login_redirect_url(self, request: HttpRequest) -> str:
2324
2425
:return: The URL of the redirect.
2526
"""
26-
return request.GET.get('next', '/user')
27+
return get_next_redirect_url(request) or '/user'
2728

2829
def get_logout_redirect_url(self, request: HttpRequest) -> str:
2930
"""
@@ -33,7 +34,7 @@ def get_logout_redirect_url(self, request: HttpRequest) -> str:
3334
3435
:return: The URL of the redirect.
3536
"""
36-
return request.POST.get('next', '/')
37+
return get_next_redirect_url(request) or '/'
3738

3839

3940
class SocialAccountAdapter(DefaultSocialAccountAdapter):
@@ -49,7 +50,7 @@ def get_connect_redirect_url(self, request: HttpRequest,
4950
5051
:return: The URL of the redirect.
5152
"""
52-
return request.POST.get('next', '/user')
53+
return get_next_redirect_url(request) or '/user'
5354

5455

5556
__all__ = ['AccountAdapter', 'SocialAccountAdapter']

users/tests/test_adapters.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ def setup_method(self):
1515
self.request.GET = {'next': self.next_url}
1616
self.request.POST = {'next': self.next_url}
1717
self.empty_request = HttpRequest()
18+
self.external_request = HttpRequest()
19+
self.external_request.GET = {'next': 'https://test.com'}
1820
self.adapter = AccountAdapter()
1921
self.social_adapter = SocialAccountAdapter()
2022

@@ -28,6 +30,10 @@ def test_get_login_redirect_url_no_next(self):
2830
assert '/user' == self.adapter \
2931
.get_login_redirect_url(self.empty_request)
3032

33+
def test_get_login_redirect_url_external(self):
34+
assert '/user' == self.adapter \
35+
.get_login_redirect_url(self.external_request)
36+
3137
def test_get_logout_redirect_url(self):
3238
assert self.next_url == self.adapter \
3339
.get_logout_redirect_url(self.request)
@@ -36,6 +42,10 @@ def test_get_logout_redirect_url_no_next(self):
3642
assert '/' == self.adapter \
3743
.get_logout_redirect_url(self.empty_request)
3844

45+
def test_get_logout_redirect_url_external(self):
46+
assert '/' == self.adapter \
47+
.get_logout_redirect_url(self.external_request)
48+
3949

4050
class TestSocialAccountAdapter(UserAdapterTestBase):
4151
def setup_method(self):
@@ -45,9 +55,16 @@ def setup_method(self):
4555
)
4656

4757
def test_get_connect_redirect_url(self):
48-
assert self.next_url == self.social_adapter \
49-
.get_connect_redirect_url(self.request, self.social_account)
58+
assert self.next_url == self.social_adapter.get_connect_redirect_url(
59+
self.request, self.social_account
60+
)
5061

5162
def test_get_connect_redirect_url_no_next(self):
52-
assert '/user' == self.social_adapter \
53-
.get_connect_redirect_url(self.empty_request, self.social_account)
63+
assert '/user' == self.social_adapter.get_connect_redirect_url(
64+
self.empty_request, self.social_account
65+
)
66+
67+
def test_get_connect_redirect_url_external(self):
68+
assert '/user' == self.social_adapter.get_connect_redirect_url(
69+
self.external_request, self.social_account
70+
)

0 commit comments

Comments
 (0)