Hi Salvatore,

> With the 0017-CVE-2019-3498.patch patch there is something strange.
> While it touches correctly the files django/views/defaults.py and the
> tests, it touches and modifies files in debian/*, other patches and
> series file.

Thanks for your review. I went through my shell's history and
unpicked what happened; whilst I had created and tested a regular
patch file at debian/patches/CVE-2019-3498.patch I wanted to store
everything in DPMT's Git repository and, as part of that,
accidentally used git commit --whilst on the magic git-pq(1) branch
and thus included all of these nonsense changes.

Updated patch attached.


Regards,

-- 
      ,''`.
     : :'  :     Chris Lamb
     `. `'`      la...@debian.org / chris-lamb.co.uk
       `-
diff --git a/debian/changelog b/debian/changelog
index b1c56f7c5..fa89c8b21 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+python-django (1:1.10.7-2+deb9u4) stretch-security; urgency=high
+
+  * CVE-2019-3498: Prevent a content-spoofing vulnerability in the default
+    404 page. (Closes: #918230)
+
+ -- Chris Lamb <la...@debian.org>  Sun, 06 Jan 2019 09:35:11 +0100
+
 python-django (1:1.10.7-2+deb9u3) stretch; urgency=medium
 
   * Default to supporting Spatialite >= 4.2. (Closes: #910240)
diff --git a/debian/patches/0017-CVE-2019-3498.patch 
b/debian/patches/0017-CVE-2019-3498.patch
new file mode 100644
index 000000000..588db30a8
--- /dev/null
+++ b/debian/patches/0017-CVE-2019-3498.patch
@@ -0,0 +1,95 @@
+From: Tom Hacohen <t...@users.noreply.github.com>
+Date: Fri, 4 Jan 2019 02:21:55 +0000
+Subject: Fixed #30070,
+ CVE-2019-3498 -- Fixed content spoofing possiblity in the default 404 page.
+
+Co-Authored-By: Tim Graham <timogra...@gmail.com>
+Backport of 1ecc0a395be721e987e8e9fdfadde952b6dee1c7 from master.
+---
+ django/views/defaults.py |  8 +++++---
+ tests/handlers/tests.py  | 12 ++++++++----
+ 2 files changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/django/views/defaults.py b/django/views/defaults.py
+index 348837e..5ec9ac8 100644
+--- a/django/views/defaults.py
++++ b/django/views/defaults.py
+@@ -2,6 +2,7 @@ from django import http
+ from django.template import Context, Engine, TemplateDoesNotExist, loader
+ from django.utils import six
+ from django.utils.encoding import force_text
++from django.utils.http import urlquote
+ from django.views.decorators.csrf import requires_csrf_token
+ 
+ ERROR_404_TEMPLATE_NAME = '404.html'
+@@ -21,7 +22,8 @@ def page_not_found(request, exception, 
template_name=ERROR_404_TEMPLATE_NAME):
+     Templates: :template:`404.html`
+     Context:
+         request_path
+-            The path of the requested URL (e.g., '/app/pages/bad_page/')
++            The path of the requested URL (e.g., '/app/pages/bad_page/'). It's
++            quoted to prevent a content injection attack.
+         exception
+             The message from the exception which triggered the 404 (if one was
+             supplied), or the exception class name
+@@ -37,7 +39,7 @@ def page_not_found(request, exception, 
template_name=ERROR_404_TEMPLATE_NAME):
+         if isinstance(message, six.text_type):
+             exception_repr = message
+     context = {
+-        'request_path': request.path,
++        'request_path': urlquote(request.path),
+         'exception': exception_repr,
+     }
+     try:
+@@ -50,7 +52,7 @@ def page_not_found(request, exception, 
template_name=ERROR_404_TEMPLATE_NAME):
+             raise
+         template = Engine().from_string(
+             '<h1>Not Found</h1>'
+-            '<p>The requested URL {{ request_path }} was not found on this 
server.</p>')
++            '<p>The requested resource was not found on this server.</p>')
+         body = template.render(Context(context))
+         content_type = 'text/html'
+     return http.HttpResponseNotFound(body, content_type=content_type)
+diff --git a/tests/handlers/tests.py b/tests/handlers/tests.py
+index 9f01cb2..50a3488 100644
+--- a/tests/handlers/tests.py
++++ b/tests/handlers/tests.py
+@@ -2,6 +2,7 @@
+ 
+ from __future__ import unicode_literals
+ 
++import sys
+ import unittest
+ 
+ from django.core.exceptions import ImproperlyConfigured
+@@ -19,6 +20,8 @@ try:
+ except ImportError:  # Python < 3.5
+     HTTPStatus = None
+ 
++PY37 = sys.version_info >= (3, 7, 0)
++
+ 
+ class HandlerTests(SimpleTestCase):
+ 
+@@ -180,16 +183,17 @@ class HandlerRequestTests(SimpleTestCase):
+ 
+     def test_invalid_urls(self):
+         response = self.client.get('~%A9helloworld')
+-        self.assertContains(response, '~%A9helloworld', status_code=404)
++        self.assertEqual(response.status_code, 404)
++        self.assertEqual(response.context['request_path'], 
'/~%25A9helloworld' if PY37 else '/%7E%25A9helloworld')
+ 
+         response = self.client.get('d%aao%aaw%aan%aal%aao%aaa%aad%aa/')
+-        self.assertContains(response, 'd%AAo%AAw%AAn%AAl%AAo%AAa%AAd%AA', 
status_code=404)
++        self.assertEqual(response.context['request_path'], 
'/d%25AAo%25AAw%25AAn%25AAl%25AAo%25AAa%25AAd%25AA')
+ 
+         response = self.client.get('/%E2%99%E2%99%A5/')
+-        self.assertContains(response, '%E2%99\u2665', status_code=404)
++        self.assertEqual(response.context['request_path'], 
'/%25E2%2599%E2%99%A5/')
+ 
+         response = self.client.get('/%E2%98%8E%E2%A9%E2%99%A5/')
+-        self.assertContains(response, '\u260e%E2%A9\u2665', status_code=404)
++        self.assertEqual(response.context['request_path'], 
'/%E2%98%8E%25E2%25A9%E2%99%A5/')
+ 
+     def test_environ_path_info_type(self):
+         environ = RequestFactory().get('/%E2%A8%87%87%A5%E2%A8%A0').environ
diff --git a/debian/patches/series b/debian/patches/series
index 6ccbb746a..5bda383eb 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -8,3 +8,4 @@ fix-test-middleware-classes-headers.patch
 0015-CVE-2018-14574.patch
 0016-CVE-2017-12794.patch
 0006-Default-to-supporting-Spatialite-4.2.patch
+0017-CVE-2019-3498.patch

Reply via email to