[Python-modules-commits] r22801 - in packages/python-django/branches/squeeze/debian (3 files)
hertzog at users.alioth.debian.org
hertzog at users.alioth.debian.org
Mon Oct 22 08:32:10 UTC 2012
Date: Monday, October 22, 2012 @ 08:31:55
Author: hertzog
Revision: 22801
* Stable security upload:
https://www.djangoproject.com/weblog/2012/oct/17/security/
Fixes: CVE-2012-4520
* Add the upstream patch:
- debian/patches/19_fix_host_header_poisoning.diff
Closes: #691145
Added:
packages/python-django/branches/squeeze/debian/patches/19_fix_host_header_poisoning.diff
Modified:
packages/python-django/branches/squeeze/debian/changelog
packages/python-django/branches/squeeze/debian/patches/series
Modified: packages/python-django/branches/squeeze/debian/changelog
===================================================================
--- packages/python-django/branches/squeeze/debian/changelog 2012-10-21 09:36:40 UTC (rev 22800)
+++ packages/python-django/branches/squeeze/debian/changelog 2012-10-22 08:31:55 UTC (rev 22801)
@@ -1,3 +1,14 @@
+python-django (1.2.3-3+squeeze4) stable-security; urgency=low
+
+ * Stable security upload:
+ https://www.djangoproject.com/weblog/2012/oct/17/security/
+ Fixes: CVE-2012-4520
+ * Add the upstream patch:
+ - debian/patches/19_fix_host_header_poisoning.diff
+ Closes: #691145
+
+ -- Raphaël Hertzog <hertzog at debian.org> Mon, 22 Oct 2012 10:19:12 +0200
+
python-django (1.2.3-3+squeeze3) stable-security; urgency=high
* Stable security upload:
Added: packages/python-django/branches/squeeze/debian/patches/19_fix_host_header_poisoning.diff
===================================================================
--- packages/python-django/branches/squeeze/debian/patches/19_fix_host_header_poisoning.diff (rev 0)
+++ packages/python-django/branches/squeeze/debian/patches/19_fix_host_header_poisoning.diff 2012-10-22 08:31:55 UTC (rev 22801)
@@ -0,0 +1,102 @@
+Description: Fix Host header poisoning
+Origin: upstream, https://github.com/django/django/commit/b45c377f8f488955e0c7069cad3f3dd21910b071/download
+Bug-Debian: http://bugs.debian.org/691145
+
+diff --git a/django/contrib/auth/tests/urls.py b/django/contrib/auth/tests/urls.py
+index 3d76a4e..c01964f 100644
+--- a/django/contrib/auth/tests/urls.py
++++ b/django/contrib/auth/tests/urls.py
+@@ -19,6 +19,7 @@ urlpatterns = urlpatterns + patterns('',
+ (r'^logout/next_page/$', 'django.contrib.auth.views.logout', dict(next_page='/somewhere/')),
+ (r'^remote_user/$', remote_user_auth_view),
+ (r'^password_reset_from_email/$', 'django.contrib.auth.views.password_reset', dict(from_email='staffmember at example.com')),
++ (r'^admin_password_reset/$', 'django.contrib.auth.views.password_reset', dict(is_admin_site=True)),
+ (r'^login_required/$', login_required(password_reset)),
+ (r'^login_required_login_url/$', login_required(password_reset, login_url='/somewhere/')),
+ )
+diff --git a/django/contrib/auth/tests/views.py b/django/contrib/auth/tests/views.py
+index b03489c..046d00d 100644
+--- a/django/contrib/auth/tests/views.py
++++ b/django/contrib/auth/tests/views.py
+@@ -9,6 +9,7 @@ from django.contrib.sites.models import Site, RequestSite
+ from django.contrib.auth.models import User
+ from django.test import TestCase
+ from django.core import mail
++from django.core.exceptions import SuspiciousOperation
+ from django.core.urlresolvers import reverse
+ from django.http import QueryDict
+
+@@ -69,6 +70,44 @@ class PasswordResetTest(AuthViewsTestCase):
+ self.assertEqual(len(mail.outbox), 1)
+ self.assertEqual("staffmember at example.com", mail.outbox[0].from_email)
+
++ def test_admin_reset(self):
++ "If the reset view is marked as being for admin, the HTTP_HOST header is used for a domain override."
++ response = self.client.post('/admin_password_reset/',
++ {'email': 'staffmember at example.com'},
++ HTTP_HOST='adminsite.com'
++ )
++ self.assertEqual(response.status_code, 302)
++ self.assertEqual(len(mail.outbox), 1)
++ self.assertTrue("http://adminsite.com" in mail.outbox[0].body)
++ self.assertEqual(settings.DEFAULT_FROM_EMAIL, mail.outbox[0].from_email)
++
++ def test_poisoned_http_host(self):
++ "Poisoned HTTP_HOST headers can't be used for reset emails"
++ # This attack is based on the way browsers handle URLs. The colon
++ # should be used to separate the port, but if the URL contains an @,
++ # the colon is interpreted as part of a username for login purposes,
++ # making 'evil.com' the request domain. Since HTTP_HOST is used to
++ # produce a meaningful reset URL, we need to be certain that the
++ # HTTP_HOST header isn't poisoned. This is done as a check when get_host()
++ # is invoked, but we check here as a practical consequence.
++ def test_host_poisoning():
++ self.client.post('/password_reset/',
++ {'email': 'staffmember at example.com'},
++ HTTP_HOST='www.example:dr.frankenstein at evil.tld'
++ )
++ self.assertRaises(SuspiciousOperation, test_host_poisoning)
++ self.assertEqual(len(mail.outbox), 0)
++
++ def test_poisoned_http_host_admin_site(self):
++ "Poisoned HTTP_HOST headers can't be used for reset emails on admin views"
++ def test_host_poisoning():
++ self.client.post('/admin_password_reset/',
++ {'email': 'staffmember at example.com'},
++ HTTP_HOST='www.example:dr.frankenstein at evil.tld'
++ )
++ self.assertRaises(SuspiciousOperation, test_host_poisoning)
++ self.assertEqual(len(mail.outbox), 0)
++
+ def _test_confirm_start(self):
+ # Start by creating the email
+ response = self.client.post('/password_reset/', {'email': 'staffmember at example.com'})
+diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py
+index eba83a2..727e916 100644
+--- a/django/contrib/auth/views.py
++++ b/django/contrib/auth/views.py
+@@ -151,7 +151,7 @@ def password_reset(request, is_admin_site=False,
+ 'request': request,
+ }
+ if is_admin_site:
+- opts = dict(opts, domain_override=request.META['HTTP_HOST'])
++ opts = dict(opts, domain_override=request.get_host())
+ form.save(**opts)
+ return HttpResponseRedirect(post_reset_redirect)
+ else:
+diff --git a/django/http/__init__.py b/django/http/__init__.py
+index 2dfe12e..dddd9a8 100644
+--- a/django/http/__init__.py
++++ b/django/http/__init__.py
+@@ -165,6 +165,11 @@ class HttpRequest(object):
+ server_port = str(self.META['SERVER_PORT'])
+ if server_port != (self.is_secure() and '443' or '80'):
+ host = '%s:%s' % (host, server_port)
++
++ # Disallow potentially poisoned hostnames.
++ if set(';/?@&=+$,').intersection(host):
++ raise SuspiciousOperation('Invalid HTTP_HOST header: %s' % host)
++
+ return host
+
+ def get_full_path(self):
Modified: packages/python-django/branches/squeeze/debian/patches/series
===================================================================
--- packages/python-django/branches/squeeze/debian/patches/series 2012-10-21 09:36:40 UTC (rev 22800)
+++ packages/python-django/branches/squeeze/debian/patches/series 2012-10-22 08:31:55 UTC (rev 22801)
@@ -15,3 +15,4 @@
16_fix_cross_site_scripting_in_authentication.diff
17_fix_dos_in_image_validation.diff
18_fix_dos_via_get_image_dimensions.diff
+19_fix_host_header_poisoning.diff
More information about the Python-modules-commits
mailing list