@@ -1764,3 +1764,34 @@ def test_include_only(self):
17641764 template .Template ('{% include "child" only %}' ).render (ctx ),
17651765 'none'
17661766 )
1767+
1768+
1769+ class SSITests (unittest .TestCase ):
1770+ def setUp (self ):
1771+ self .this_dir = os .path .dirname (os .path .abspath (__file__ ))
1772+ self .ssi_dir = os .path .join (self .this_dir , "templates" , "first" )
1773+
1774+ def render_ssi (self , path ):
1775+ # the path must exist for the test to be reliable
1776+ self .assertTrue (os .path .exists (path ))
1777+ return template .Template ('{%% ssi %s %%}' % path ).render (Context ())
1778+
1779+ def test_allowed_paths (self ):
1780+ acceptable_path = os .path .join (self .ssi_dir , ".." , "first" , "test.html" )
1781+ with override_settings (ALLOWED_INCLUDE_ROOTS = (self .ssi_dir ,)):
1782+ self .assertEqual (self .render_ssi (acceptable_path ), 'First template\n ' )
1783+
1784+ def test_relative_include_exploit (self ):
1785+ """
1786+ May not bypass ALLOWED_INCLUDE_ROOTS with relative paths
1787+
1788+ e.g. if ALLOWED_INCLUDE_ROOTS = ("/var/www",), it should not be
1789+ possible to do {% ssi "/var/www/../../etc/passwd" %}
1790+ """
1791+ disallowed_paths = [
1792+ os .path .join (self .ssi_dir , ".." , "ssi_include.html" ),
1793+ os .path .join (self .ssi_dir , ".." , "second" , "test.html" ),
1794+ ]
1795+ with override_settings (ALLOWED_INCLUDE_ROOTS = (self .ssi_dir ,)):
1796+ for path in disallowed_paths :
1797+ self .assertEqual (self .render_ssi (path ), '' )
0 commit comments