Skip to content
Snippets Groups Projects
Commit e291a530 authored by Bryan BRANCOTTE's avatar Bryan BRANCOTTE
Browse files

[security] prevent redirection outside the current website

parent e20afb53
No related branches found
No related tags found
No related merge requests found
Pipeline #138315 passed
from django.shortcuts import redirect
from urllib.parse import urlparse
def redirect_same_domain(to, *args, permanent=False, **kwargs):
to = urlparse(to).path
return redirect(to, *args, permanent=permanent, **kwargs)
......@@ -56,6 +56,48 @@ class SignUpTests(TestCase):
self.assertEqual(user.email, data["email"])
class SignUpAttackWithNextParamTests(TestCase):
def setUp(self):
cache.clear()
def test_legit_redirect(self):
user_count = get_user_model().objects.count()
data = {
'username': "userAAA",
'email': "userAAA@mp.com",
'password1': "user@mp.comuser@mp.comuser@mp.comuser@mp.com",
'password2': "user@mp.comuser@mp.comuser@mp.comuser@mp.com",
'first_name': "user",
'next': reverse('basetheme_bootstrap:account'),
}
response = self.client.post(reverse('basetheme_bootstrap:signup'), data, follow=False)
self.assertEqual(response.status_code, 302)
self.assertRedirects(response, expected_url=reverse('basetheme_bootstrap:account'), )
self.assertEqual(get_user_model().objects.count(), user_count + 1)
user = get_user_model().objects.last()
self.assertEqual(user.username, data["username"])
self.assertEqual(user.email, data["email"])
def test_attacking_redirect(self):
user_count = get_user_model().objects.count()
data = {
'username': "userAAA",
'email': "userAAA@mp.com",
'password1': "user@mp.comuser@mp.comuser@mp.comuser@mp.com",
'password2': "user@mp.comuser@mp.comuser@mp.comuser@mp.com",
'first_name': "user",
'next': "https://www.attacking.com" + reverse('basetheme_bootstrap:account'),
}
response = self.client.post(reverse('basetheme_bootstrap:signup'), data, follow=False)
self.assertEqual(response.status_code, 302)
self.assertRedirects(response, expected_url=reverse('basetheme_bootstrap:account'), )
self.assertEqual(get_user_model().objects.count(), user_count + 1)
user = get_user_model().objects.last()
self.assertEqual(user.username, data["username"])
self.assertEqual(user.email, data["email"])
@override_settings(
BASETHEME_BOOTSTRAP_USERNAME_IS_EMAIL=True,
)
......@@ -143,7 +185,7 @@ class SignUpWithFirstLastNameRequiredTests(TestCase):
@override_settings(
BASETHEME_BOOTSTRAP_VALIDATE_EMAIL_BEFORE_ACTIVATION=True,
PASSWORD_RESET_TIMEOUT_DAYS=1,
PASSWORD_RESET_TIMEOUT=60*60*24,
PASSWORD_RESET_TIMEOUT=60 * 60 * 24,
)
class SignUpWithValidationTests(TestCase):
......@@ -179,7 +221,7 @@ class SignUpWithValidationTests(TestCase):
self.assertNotIn(Group.objects.get(name="PendingAccountUser"), user.groups.all())
## test an account cannot be re-activated with the link:
user.is_active=False
user.is_active = False
user.save()
self.client.post(reverse('basetheme_bootstrap:activate', args=[m[0][0], m[0][1] + "-" + m[0][2]]))
self.assertFalse(get_user_model().objects.last().is_active)
......@@ -260,11 +302,11 @@ class TestWithTemplatesInPlace(SignUpTests):
@override_settings(
BASETHEME_BOOTSTRAP_VALIDATE_EMAIL_BEFORE_ACTIVATION=True,
BASETHEME_BOOTSTRAP_VALIDATE_EMAIL_BEFORE_ACTIVATION=True,
)
class SuperuserSignUpTests(TestCase):
def test_sign_up_for_superuser(self):
#even with BASETHEME_BOOTSTRAP_VALIDATE_EMAIL_BEFORE_ACTIVATION to True first user must be super and active
# even with BASETHEME_BOOTSTRAP_VALIDATE_EMAIL_BEFORE_ACTIVATION to True first user must be super and active
response = self.client.post(reverse('basetheme_bootstrap:signup'), {
'username': "userAAA",
'email': "bryan.brancotte@pasteur.fr",
......@@ -272,7 +314,7 @@ class SuperuserSignUpTests(TestCase):
'password2': "user@mp.comuser@mp.comuser@mp.comuser@mp.com",
'first_name': "user"
})
self.assertEqual(response.status_code, 302)
self.assertEqual(response.status_code, 302)
self.assertTrue(get_user_model().objects.get(username="userAAA").is_superuser)
self.assertTrue(get_user_model().objects.get(username="userAAA").is_active)
......
......@@ -14,7 +14,7 @@ from django.core.mail import send_mail
from django.db.models import ProtectedError
from django.forms import widgets
from django.http import HttpResponseForbidden
from django.shortcuts import render, redirect
from django.shortcuts import render
from django.template import TemplateDoesNotExist
from django.template.defaultfilters import time as time_filter
from django.urls import reverse
......@@ -27,6 +27,7 @@ from basetheme_bootstrap import user_preferences_utils
from basetheme_bootstrap.default_settings import is_validating_email
from basetheme_bootstrap.forms import UserCreationFormWithMore, \
MyUserChangeForm, UserDeleteForm
from basetheme_bootstrap.shortcuts import redirect_same_domain as redirect
logger = logging.getLogger(__name__)
......
[metadata]
name = django-basetheme-bootstrap
version = 1.6.1
version = 1.7.0
description = Django Basetheme Bootstrap
long_description = file: README.rst
url = https://gitlab.pasteur.fr/bbrancot/django-basetheme-bootstrap
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment