VYPR
High severityNVD Advisory· Published Sep 16, 2013· Updated Apr 29, 2026

CVE-2013-4315

CVE-2013-4315

Description

Directory traversal vulnerability in Django 1.4.x before 1.4.7, 1.5.x before 1.5.3, and 1.6.x before 1.6 beta 3 allows remote attackers to read arbitrary files via a file path in the ALLOWED_INCLUDE_ROOTS setting followed by a .. (dot dot) in a ssi template tag.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
DjangoPyPI
>= 1.4, < 1.4.71.4.7
DjangoPyPI
>= 1.5, < 1.5.31.5.3

Affected products

12
  • cpe:2.3:a:djangoproject:django:1.4:*:*:*:*:*:*:*+ 11 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.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.5:*:*:*:*:*:*:*
    • 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.5.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6:beta1:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6:beta2:*:*:*:*:*:*

Patches

2
87d2750b39f6

[1.4.x] Prevented arbitrary file inclusion with {% ssi %} tag and relative paths.

https://github.com/django/djangoTim GrahamAug 28, 2013via ghsa
2 files changed · +33 0
  • django/template/defaulttags.py+2 0 modified
    @@ -1,5 +1,6 @@
     """Default tags used by the template system, available to all templates."""
     
    +import os
     import sys
     import re
     from datetime import datetime
    @@ -309,6 +310,7 @@ def render(self, context):
             return ''
     
     def include_is_allowed(filepath):
    +    filepath = os.path.abspath(filepath)
         for root in settings.ALLOWED_INCLUDE_ROOTS:
             if filepath.startswith(root):
                 return True
    
  • tests/regressiontests/templates/tests.py+31 0 modified
    @@ -1764,3 +1764,34 @@ def test_include_only(self):
                 template.Template('{% include "child" only %}').render(ctx),
                 'none'
             )
    +
    +
    +class SSITests(unittest.TestCase):
    +    def setUp(self):
    +        self.this_dir = os.path.dirname(os.path.abspath(__file__))
    +        self.ssi_dir = os.path.join(self.this_dir, "templates", "first")
    +
    +    def render_ssi(self, path):
    +        # the path must exist for the test to be reliable
    +        self.assertTrue(os.path.exists(path))
    +        return template.Template('{%% ssi %s %%}' % path).render(Context())
    +
    +    def test_allowed_paths(self):
    +        acceptable_path = os.path.join(self.ssi_dir, "..", "first", "test.html")
    +        with override_settings(ALLOWED_INCLUDE_ROOTS=(self.ssi_dir,)):
    +            self.assertEqual(self.render_ssi(acceptable_path), 'First template\n')
    +
    +    def test_relative_include_exploit(self):
    +        """
    +        May not bypass ALLOWED_INCLUDE_ROOTS with relative paths
    +
    +        e.g. if ALLOWED_INCLUDE_ROOTS = ("/var/www",), it should not be
    +        possible to do {% ssi "/var/www/../../etc/passwd" %}
    +        """
    +        disallowed_paths = [
    +            os.path.join(self.ssi_dir, "..", "ssi_include.html"),
    +            os.path.join(self.ssi_dir, "..", "second", "test.html"),
    +        ]
    +        with override_settings(ALLOWED_INCLUDE_ROOTS=(self.ssi_dir,)):
    +            for path in disallowed_paths:
    +                self.assertEqual(self.render_ssi(path), '')
    
988b61c550d7

[1.5.x] Prevented arbitrary file inclusion with {% ssi %} tag and relative paths.

https://github.com/django/djangoTim GrahamAug 27, 2013via ghsa
2 files changed · +33 0
  • django/template/defaulttags.py+2 0 modified
    @@ -1,6 +1,7 @@
     """Default tags used by the template system, available to all templates."""
     from __future__ import unicode_literals
     
    +import os
     import sys
     import re
     from datetime import datetime
    @@ -312,6 +313,7 @@ def render(self, context):
             return ''
     
     def include_is_allowed(filepath):
    +    filepath = os.path.abspath(filepath)
         for root in settings.ALLOWED_INCLUDE_ROOTS:
             if filepath.startswith(root):
                 return True
    
  • tests/regressiontests/templates/tests.py+31 0 modified
    @@ -1737,3 +1737,34 @@ def test_include_only(self):
                 template.Template('{% include "child" only %}').render(ctx),
                 'none'
             )
    +
    +
    +class SSITests(TestCase):
    +    def setUp(self):
    +        self.this_dir = os.path.dirname(os.path.abspath(upath(__file__)))
    +        self.ssi_dir = os.path.join(self.this_dir, "templates", "first")
    +
    +    def render_ssi(self, path):
    +        # the path must exist for the test to be reliable
    +        self.assertTrue(os.path.exists(path))
    +        return template.Template('{%% ssi "%s" %%}' % path).render(Context())
    +
    +    def test_allowed_paths(self):
    +        acceptable_path = os.path.join(self.ssi_dir, "..", "first", "test.html")
    +        with override_settings(ALLOWED_INCLUDE_ROOTS=(self.ssi_dir,)):
    +            self.assertEqual(self.render_ssi(acceptable_path), 'First template\n')
    +
    +    def test_relative_include_exploit(self):
    +        """
    +        May not bypass ALLOWED_INCLUDE_ROOTS with relative paths
    +
    +        e.g. if ALLOWED_INCLUDE_ROOTS = ("/var/www",), it should not be
    +        possible to do {% ssi "/var/www/../../etc/passwd" %}
    +        """
    +        disallowed_paths = [
    +            os.path.join(self.ssi_dir, "..", "ssi_include.html"),
    +            os.path.join(self.ssi_dir, "..", "second", "test.html"),
    +        ]
    +        with override_settings(ALLOWED_INCLUDE_ROOTS=(self.ssi_dir,)):
    +            for path in disallowed_paths:
    +                self.assertEqual(self.render_ssi(path), '')
    

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

12

News mentions

0

No linked articles in our index yet.