VYPR
Critical severityNVD Advisory· Published May 16, 2014· Updated May 6, 2026

CVE-2014-1418

CVE-2014-1418

Description

Django 1.4 before 1.4.13, 1.5 before 1.5.8, 1.6 before 1.6.5, and 1.7 before 1.7b4 does not properly include the (1) Vary: Cookie or (2) Cache-Control header in responses, which allows remote attackers to obtain sensitive information or poison the cache via a request from certain browsers.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
DjangoPyPI
>= 1.4, < 1.4.131.4.13
DjangoPyPI
>= 1.5, < 1.5.81.5.8
DjangoPyPI
>= 1.6, < 1.6.51.6.5
DjangoPyPI
>= 1.7a1, < 1.7b41.7b4

Affected products

39
  • cpe:2.3:a:djangoproject:django:1.4:*:*:*:*:*:*:*+ 33 more
    • cpe:2.3:a:djangoproject:django:1.4:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.10:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.11:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.12:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.2:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.4:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.5:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.6:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.7:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.8:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.9:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.2:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.3:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.4:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.5:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.6:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.7:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5:alpha:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5:beta:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6:-:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.2:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.3:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.4:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6:beta1:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6:beta2:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6:beta3:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6:beta4:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7:beta1:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7:beta2:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7:beta3:*:*:*:*:*:*
  • cpe:2.3:o:canonical:ubuntu_linux:10.04:-:lts:*:*:*:*:*+ 4 more
    • cpe:2.3:o:canonical:ubuntu_linux:10.04:-:lts:*:*:*:*:*
    • cpe:2.3:o:canonical:ubuntu_linux:12.04:-:lts:*:*:*:*:*
    • cpe:2.3:o:canonical:ubuntu_linux:12.10:*:*:*:*:*:*:*
    • cpe:2.3:o:canonical:ubuntu_linux:13.10:*:*:*:*:*:*:*
    • cpe:2.3:o:canonical:ubuntu_linux:14.04:*:*:*:lts:*:*:*

Patches

3
28e23306aa53

[1.4.x] Dropped fix_IE_for_vary/attach.

https://github.com/django/djangoAymeric AugustinMay 12, 2014via ghsa
3 files changed · +0 100
  • django/core/handlers/base.py+0 2 modified
    @@ -14,8 +14,6 @@ class BaseHandler(object):
         response_fixes = [
             http.fix_location_header,
             http.conditional_content_removal,
    -        http.fix_IE_for_attach,
    -        http.fix_IE_for_vary,
         ]
     
         def __init__(self):
    
  • django/http/utils.py+0 54 modified
    @@ -31,57 +31,3 @@ def conditional_content_removal(request, response):
         if request.method == 'HEAD':
             response.content = ''
         return response
    -
    -def fix_IE_for_attach(request, response):
    -    """
    -    This function will prevent Django from serving a Content-Disposition header
    -    while expecting the browser to cache it (only when the browser is IE). This
    -    leads to IE not allowing the client to download.
    -    """
    -    useragent = request.META.get('HTTP_USER_AGENT', '').upper()
    -    if 'MSIE' not in useragent and 'CHROMEFRAME' not in useragent:
    -        return response
    -
    -    offending_headers = ('no-cache', 'no-store')
    -    if response.has_header('Content-Disposition'):
    -        try:
    -            del response['Pragma']
    -        except KeyError:
    -            pass
    -        if response.has_header('Cache-Control'):
    -            cache_control_values = [value.strip() for value in
    -                    response['Cache-Control'].split(',')
    -                    if value.strip().lower() not in offending_headers]
    -
    -            if not len(cache_control_values):
    -                del response['Cache-Control']
    -            else:
    -                response['Cache-Control'] = ', '.join(cache_control_values)
    -
    -    return response
    -
    -def fix_IE_for_vary(request, response):
    -    """
    -    This function will fix the bug reported at
    -    http://support.microsoft.com/kb/824847/en-us?spid=8722&sid=global
    -    by clearing the Vary header whenever the mime-type is not safe
    -    enough for Internet Explorer to handle.  Poor thing.
    -    """
    -    useragent = request.META.get('HTTP_USER_AGENT', '').upper()
    -    if 'MSIE' not in useragent and 'CHROMEFRAME' not in useragent:
    -        return response
    -
    -    # These mime-types that are decreed "Vary-safe" for IE:
    -    safe_mime_types = ('text/html', 'text/plain', 'text/sgml')
    -
    -    # The first part of the Content-Type field will be the MIME type,
    -    # everything after ';', such as character-set, can be ignored.
    -    mime_type = response.get('Content-Type', '').partition(';')[0]
    -    if mime_type not in safe_mime_types:
    -        try:
    -            del response['Vary']
    -        except KeyError:
    -            pass
    -
    -    return response
    -
    
  • tests/regressiontests/utils/http.py+0 44 modified
    @@ -56,50 +56,6 @@ def test_urlencode(self):
             ]
             self.assertTrue(result in acceptable_results)
     
    -    def test_fix_IE_for_vary(self):
    -        """
    -        Regression for #16632.
    -
    -        `fix_IE_for_vary` shouldn't crash when there's no Content-Type header.
    -        """
    -
    -        # functions to generate responses
    -        def response_with_unsafe_content_type():
    -            r = HttpResponse(content_type="text/unsafe")
    -            r['Vary'] = 'Cookie'
    -            return r
    -
    -        def no_content_response_with_unsafe_content_type():
    -            # 'Content-Type' always defaulted, so delete it
    -            r = response_with_unsafe_content_type()
    -            del r['Content-Type']
    -            return r
    -
    -        # request with & without IE user agent
    -        rf = RequestFactory()
    -        request = rf.get('/')
    -        ie_request = rf.get('/', HTTP_USER_AGENT='MSIE')
    -
    -        # not IE, unsafe_content_type
    -        response = response_with_unsafe_content_type()
    -        utils.fix_IE_for_vary(request, response)
    -        self.assertTrue('Vary' in response)
    -
    -        # IE, unsafe_content_type
    -        response = response_with_unsafe_content_type()
    -        utils.fix_IE_for_vary(ie_request, response)
    -        self.assertFalse('Vary' in response)
    -
    -        # not IE, no_content
    -        response = no_content_response_with_unsafe_content_type()
    -        utils.fix_IE_for_vary(request, response)
    -        self.assertTrue('Vary' in response)
    -
    -        # IE, no_content
    -        response = no_content_response_with_unsafe_content_type()
    -        utils.fix_IE_for_vary(ie_request, response)
    -        self.assertFalse('Vary' in response)
    -
         def test_base36(self):
             # reciprocity works
             for n in [0, 1, 1000, 1000000, sys.maxint]:
    
4001ec8698f5

[1.5.x] Dropped fix_IE_for_vary/attach.

https://github.com/django/djangoAymeric AugustinMay 12, 2014via ghsa
4 files changed · +1 103
  • django/core/handlers/base.py+0 2 modified
    @@ -22,8 +22,6 @@ class BaseHandler(object):
         response_fixes = [
             http.fix_location_header,
             http.conditional_content_removal,
    -        http.fix_IE_for_attach,
    -        http.fix_IE_for_vary,
         ]
     
         def __init__(self):
    
  • django/http/__init__.py+1 2 modified
    @@ -6,5 +6,4 @@
         HttpResponseRedirect, HttpResponseNotModified, HttpResponseBadRequest,
         HttpResponseForbidden, HttpResponseNotFound, HttpResponseNotAllowed,
         HttpResponseGone, HttpResponseServerError, Http404, BadHeaderError)
    -from django.http.utils import (fix_location_header, conditional_content_removal,
    -    fix_IE_for_attach, fix_IE_for_vary)
    +from django.http.utils import fix_location_header, conditional_content_removal
    
  • django/http/utils.py+0 55 modified
    @@ -39,58 +39,3 @@ def conditional_content_removal(request, response):
             else:
                 response.content = ''
         return response
    -
    -
    -def fix_IE_for_attach(request, response):
    -    """
    -    This function will prevent Django from serving a Content-Disposition header
    -    while expecting the browser to cache it (only when the browser is IE). This
    -    leads to IE not allowing the client to download.
    -    """
    -    useragent = request.META.get('HTTP_USER_AGENT', '').upper()
    -    if 'MSIE' not in useragent and 'CHROMEFRAME' not in useragent:
    -        return response
    -
    -    offending_headers = ('no-cache', 'no-store')
    -    if response.has_header('Content-Disposition'):
    -        try:
    -            del response['Pragma']
    -        except KeyError:
    -            pass
    -        if response.has_header('Cache-Control'):
    -            cache_control_values = [value.strip() for value in
    -                    response['Cache-Control'].split(',')
    -                    if value.strip().lower() not in offending_headers]
    -
    -            if not len(cache_control_values):
    -                del response['Cache-Control']
    -            else:
    -                response['Cache-Control'] = ', '.join(cache_control_values)
    -
    -    return response
    -
    -
    -def fix_IE_for_vary(request, response):
    -    """
    -    This function will fix the bug reported at
    -    http://support.microsoft.com/kb/824847/en-us?spid=8722&sid=global
    -    by clearing the Vary header whenever the mime-type is not safe
    -    enough for Internet Explorer to handle.  Poor thing.
    -    """
    -    useragent = request.META.get('HTTP_USER_AGENT', '').upper()
    -    if 'MSIE' not in useragent and 'CHROMEFRAME' not in useragent:
    -        return response
    -
    -    # These mime-types that are decreed "Vary-safe" for IE:
    -    safe_mime_types = ('text/html', 'text/plain', 'text/sgml')
    -
    -    # The first part of the Content-Type field will be the MIME type,
    -    # everything after ';', such as character-set, can be ignored.
    -    mime_type = response.get('Content-Type', '').partition(';')[0]
    -    if mime_type not in safe_mime_types:
    -        try:
    -            del response['Vary']
    -        except KeyError:
    -            pass
    -
    -    return response
    
  • tests/regressiontests/utils/http.py+0 44 modified
    @@ -67,50 +67,6 @@ def test_urlencode(self):
             ]
             self.assertTrue(result in acceptable_results)
     
    -    def test_fix_IE_for_vary(self):
    -        """
    -        Regression for #16632.
    -
    -        `fix_IE_for_vary` shouldn't crash when there's no Content-Type header.
    -        """
    -
    -        # functions to generate responses
    -        def response_with_unsafe_content_type():
    -            r = HttpResponse(content_type="text/unsafe")
    -            r['Vary'] = 'Cookie'
    -            return r
    -
    -        def no_content_response_with_unsafe_content_type():
    -            # 'Content-Type' always defaulted, so delete it
    -            r = response_with_unsafe_content_type()
    -            del r['Content-Type']
    -            return r
    -
    -        # request with & without IE user agent
    -        rf = RequestFactory()
    -        request = rf.get('/')
    -        ie_request = rf.get('/', HTTP_USER_AGENT='MSIE')
    -
    -        # not IE, unsafe_content_type
    -        response = response_with_unsafe_content_type()
    -        utils.fix_IE_for_vary(request, response)
    -        self.assertTrue('Vary' in response)
    -
    -        # IE, unsafe_content_type
    -        response = response_with_unsafe_content_type()
    -        utils.fix_IE_for_vary(ie_request, response)
    -        self.assertFalse('Vary' in response)
    -
    -        # not IE, no_content
    -        response = no_content_response_with_unsafe_content_type()
    -        utils.fix_IE_for_vary(request, response)
    -        self.assertTrue('Vary' in response)
    -
    -        # IE, no_content
    -        response = no_content_response_with_unsafe_content_type()
    -        utils.fix_IE_for_vary(ie_request, response)
    -        self.assertFalse('Vary' in response)
    -
         def test_base36(self):
             # reciprocity works
             for n in [0, 1, 1000, 1000000]:
    
1abcf3a808b3

[1.6.x] Dropped fix_IE_for_vary/attach.

https://github.com/django/djangoAymeric AugustinMay 12, 2014via ghsa
4 files changed · +1 103
  • django/core/handlers/base.py+0 2 modified
    @@ -23,8 +23,6 @@ class BaseHandler(object):
         response_fixes = [
             http.fix_location_header,
             http.conditional_content_removal,
    -        http.fix_IE_for_attach,
    -        http.fix_IE_for_vary,
         ]
     
         def __init__(self):
    
  • django/http/__init__.py+1 2 modified
    @@ -6,5 +6,4 @@
         HttpResponseRedirect, HttpResponseNotModified, HttpResponseBadRequest,
         HttpResponseForbidden, HttpResponseNotFound, HttpResponseNotAllowed,
         HttpResponseGone, HttpResponseServerError, Http404, BadHeaderError)
    -from django.http.utils import (fix_location_header, conditional_content_removal,
    -    fix_IE_for_attach, fix_IE_for_vary)
    +from django.http.utils import fix_location_header, conditional_content_removal
    
  • django/http/utils.py+0 55 modified
    @@ -39,58 +39,3 @@ def conditional_content_removal(request, response):
             else:
                 response.content = b''
         return response
    -
    -
    -def fix_IE_for_attach(request, response):
    -    """
    -    This function will prevent Django from serving a Content-Disposition header
    -    while expecting the browser to cache it (only when the browser is IE). This
    -    leads to IE not allowing the client to download.
    -    """
    -    useragent = request.META.get('HTTP_USER_AGENT', '').upper()
    -    if 'MSIE' not in useragent and 'CHROMEFRAME' not in useragent:
    -        return response
    -
    -    offending_headers = ('no-cache', 'no-store')
    -    if response.has_header('Content-Disposition'):
    -        try:
    -            del response['Pragma']
    -        except KeyError:
    -            pass
    -        if response.has_header('Cache-Control'):
    -            cache_control_values = [value.strip() for value in
    -                    response['Cache-Control'].split(',')
    -                    if value.strip().lower() not in offending_headers]
    -
    -            if not len(cache_control_values):
    -                del response['Cache-Control']
    -            else:
    -                response['Cache-Control'] = ', '.join(cache_control_values)
    -
    -    return response
    -
    -
    -def fix_IE_for_vary(request, response):
    -    """
    -    This function will fix the bug reported at
    -    http://support.microsoft.com/kb/824847/en-us?spid=8722&sid=global
    -    by clearing the Vary header whenever the mime-type is not safe
    -    enough for Internet Explorer to handle.  Poor thing.
    -    """
    -    useragent = request.META.get('HTTP_USER_AGENT', '').upper()
    -    if 'MSIE' not in useragent and 'CHROMEFRAME' not in useragent:
    -        return response
    -
    -    # These mime-types that are decreed "Vary-safe" for IE:
    -    safe_mime_types = ('text/html', 'text/plain', 'text/sgml')
    -
    -    # The first part of the Content-Type field will be the MIME type,
    -    # everything after ';', such as character-set, can be ignored.
    -    mime_type = response.get('Content-Type', '').partition(';')[0]
    -    if mime_type not in safe_mime_types:
    -        try:
    -            del response['Vary']
    -        except KeyError:
    -            pass
    -
    -    return response
    
  • tests/utils_tests/test_http.py+0 44 modified
    @@ -67,50 +67,6 @@ def test_urlencode(self):
             ]
             self.assertTrue(result in acceptable_results)
     
    -    def test_fix_IE_for_vary(self):
    -        """
    -        Regression for #16632.
    -
    -        `fix_IE_for_vary` shouldn't crash when there's no Content-Type header.
    -        """
    -
    -        # functions to generate responses
    -        def response_with_unsafe_content_type():
    -            r = HttpResponse(content_type="text/unsafe")
    -            r['Vary'] = 'Cookie'
    -            return r
    -
    -        def no_content_response_with_unsafe_content_type():
    -            # 'Content-Type' always defaulted, so delete it
    -            r = response_with_unsafe_content_type()
    -            del r['Content-Type']
    -            return r
    -
    -        # request with & without IE user agent
    -        rf = RequestFactory()
    -        request = rf.get('/')
    -        ie_request = rf.get('/', HTTP_USER_AGENT='MSIE')
    -
    -        # not IE, unsafe_content_type
    -        response = response_with_unsafe_content_type()
    -        utils.fix_IE_for_vary(request, response)
    -        self.assertTrue('Vary' in response)
    -
    -        # IE, unsafe_content_type
    -        response = response_with_unsafe_content_type()
    -        utils.fix_IE_for_vary(ie_request, response)
    -        self.assertFalse('Vary' in response)
    -
    -        # not IE, no_content
    -        response = no_content_response_with_unsafe_content_type()
    -        utils.fix_IE_for_vary(request, response)
    -        self.assertTrue('Vary' in response)
    -
    -        # IE, no_content
    -        response = no_content_response_with_unsafe_content_type()
    -        utils.fix_IE_for_vary(ie_request, response)
    -        self.assertFalse('Vary' in response)
    -
         def test_base36(self):
             # reciprocity works
             for n in [0, 1, 1000, 1000000]:
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

14

News mentions

0

No linked articles in our index yet.