Ticket #11457: 11457-4.patch
File 11457-4.patch, 3.9 KB (added by , 15 years ago) |
---|
-
django/contrib/auth/views.py
15 15 from django.contrib.auth.models import User 16 16 from django.views.decorators.cache import never_cache 17 17 18 import re 19 18 20 @csrf_protect 19 21 @never_cache 20 22 def login(request, template_name='registration/login.html', … … 26 28 form = authentication_form(data=request.POST) 27 29 if form.is_valid(): 28 30 # Light security check -- make sure redirect_to isn't garbage. 29 if not redirect_to or ' //' in redirect_to or '' in redirect_to:31 if not redirect_to or ' ' in redirect_to: 30 32 redirect_to = settings.LOGIN_REDIRECT_URL 33 elif '//' in redirect_to: 34 # Heavier security check -- http://example.com should not be 35 # allowed, but /view/?param=http://example.com is fine 36 # This regex checks if there is a '//' *before* a question mark 37 if re.match(r'[^\?]*//', redirect_to): 38 redirect_to = settings.LOGIN_REDIRECT_URL 31 39 from django.contrib.auth import login 32 40 login(request, form.get_user()) 33 41 if request.session.test_cookie_worked(): -
django/contrib/auth/tests/views.py
2 2 import re 3 3 4 4 from django.conf import settings 5 from django.contrib.auth import SESSION_KEY 5 from django.contrib.auth import SESSION_KEY, REDIRECT_FIELD_NAME 6 6 from django.contrib.auth.forms import AuthenticationForm 7 7 from django.contrib.sites.models import Site, RequestSite 8 8 from django.contrib.auth.models import User … … 183 183 self.assertEquals(response.context['site_name'], site.name) 184 184 self.assert_(isinstance(response.context['form'], AuthenticationForm), 185 185 'Login form is not an AuthenticationForm') 186 187 def test_security_check(self, password='password'): 188 import urllib 189 login_url = reverse('django.contrib.auth.views.login') 190 191 # Those URLs should not pass the security check 192 for bad_url in ('http://example.com', 193 'https://example.com', 194 'ftp://exampel.com', 195 '//example.com'): 196 197 nasty_url = '%(url)s?%(next)s=%(bad_url)s' % { 198 'url': login_url, 199 'next': REDIRECT_FIELD_NAME, 200 'bad_url': urllib.quote(bad_url) 201 } 202 response = self.client.post(nasty_url, { 203 'username': 'testclient', 204 'password': password, 205 } 206 ) 207 self.assertEquals(response.status_code, 302) 208 self.assertFalse(bad_url in response['Location'], "%s should be blocked" % bad_url) 209 210 # Now, these URLs have an other URL as a GET parameter and therefore 211 # should be allowed 212 for url_ in ('http://example.com', 'https://example.com', 213 'ftp://exampel.com', '//example.com'): 214 safe_url = '%(url)s?%(next)s=/view/?param=%(safe_param)s' % { 215 'url': login_url, 216 'next': REDIRECT_FIELD_NAME, 217 'safe_param': urllib.quote(url_) 218 } 219 response = self.client.post(safe_url, { 220 'username': 'testclient', 221 'password': password, 222 } 223 ) 224 self.assertEquals(response.status_code, 302) 225 self.assertTrue('/view/?param=%s' % url_ in response['Location'], "/view/?param=%s should be allowed" % url_) 226 186 227 187 228 class LogoutTest(AuthViewsTestCase): 188 229 urls = 'django.contrib.auth.tests.urls'