Kaydet (Commit) 04ee4059 authored tarafından Tim Graham's avatar Tim Graham

Refs #24022 -- Removed the ssi tag per deprecation timeline.

üst 3af9b700
...@@ -99,7 +99,6 @@ class Settings(BaseSettings): ...@@ -99,7 +99,6 @@ class Settings(BaseSettings):
mod = importlib.import_module(self.SETTINGS_MODULE) mod = importlib.import_module(self.SETTINGS_MODULE)
tuple_settings = ( tuple_settings = (
"ALLOWED_INCLUDE_ROOTS",
"INSTALLED_APPS", "INSTALLED_APPS",
"TEMPLATE_DIRS", "TEMPLATE_DIRS",
"LOCALE_PATHS", "LOCALE_PATHS",
......
...@@ -260,10 +260,6 @@ DISALLOWED_USER_AGENTS = [] ...@@ -260,10 +260,6 @@ DISALLOWED_USER_AGENTS = []
ABSOLUTE_URL_OVERRIDES = {} ABSOLUTE_URL_OVERRIDES = {}
# List of strings representing allowed prefixes for the {% ssi %} tag.
# Example: ['/home/html', '/var/www']
ALLOWED_INCLUDE_ROOTS = []
# List of compiled regular expression objects representing URLs that need not # List of compiled regular expression objects representing URLs that need not
# be reported by BrokenLinkEmailsMiddleware. Here are a few examples: # be reported by BrokenLinkEmailsMiddleware. Here are a few examples:
# import re # import re
......
...@@ -10,7 +10,6 @@ def check_duplicate_template_settings(app_configs, **kwargs): ...@@ -10,7 +10,6 @@ def check_duplicate_template_settings(app_configs, **kwargs):
if settings.TEMPLATES: if settings.TEMPLATES:
values = [ values = [
'TEMPLATE_DIRS', 'TEMPLATE_DIRS',
'ALLOWED_INCLUDE_ROOTS',
'TEMPLATE_CONTEXT_PROCESSORS', 'TEMPLATE_CONTEXT_PROCESSORS',
'TEMPLATE_DEBUG', 'TEMPLATE_DEBUG',
'TEMPLATE_LOADERS', 'TEMPLATE_LOADERS',
......
"""Default tags used by the template system, available to all templates.""" """Default tags used by the template system, available to all templates."""
from __future__ import unicode_literals from __future__ import unicode_literals
import os
import re import re
import sys import sys
import warnings import warnings
...@@ -19,7 +18,7 @@ from django.utils.safestring import mark_safe ...@@ -19,7 +18,7 @@ from django.utils.safestring import mark_safe
from .base import ( from .base import (
BLOCK_TAG_END, BLOCK_TAG_START, COMMENT_TAG_END, COMMENT_TAG_START, BLOCK_TAG_END, BLOCK_TAG_START, COMMENT_TAG_END, COMMENT_TAG_START,
SINGLE_BRACE_END, SINGLE_BRACE_START, VARIABLE_ATTRIBUTE_SEPARATOR, SINGLE_BRACE_END, SINGLE_BRACE_START, VARIABLE_ATTRIBUTE_SEPARATOR,
VARIABLE_TAG_END, VARIABLE_TAG_START, Context, Node, NodeList, Template, VARIABLE_TAG_END, VARIABLE_TAG_START, Context, Node, NodeList,
TemplateSyntaxError, VariableDoesNotExist, kwarg_re, TemplateSyntaxError, VariableDoesNotExist, kwarg_re,
render_value_in_context, token_kwargs, render_value_in_context, token_kwargs,
) )
...@@ -373,44 +372,6 @@ class RegroupNode(Node): ...@@ -373,44 +372,6 @@ class RegroupNode(Node):
return '' return ''
def include_is_allowed(filepath, allowed_include_roots):
filepath = os.path.abspath(filepath)
for root in allowed_include_roots:
if filepath.startswith(root):
return True
return False
class SsiNode(Node):
def __init__(self, filepath, parsed):
self.filepath = filepath
self.parsed = parsed
def render(self, context):
filepath = self.filepath.resolve(context)
if not include_is_allowed(filepath, context.template.engine.allowed_include_roots):
if settings.DEBUG:
return "[Didn't have permission to include file]"
else:
return '' # Fail silently for invalid includes.
try:
with open(filepath, 'r') as fp:
output = fp.read()
except IOError:
output = ''
if self.parsed:
try:
t = Template(output, name=filepath, engine=context.template.engine)
return t.render(context)
except TemplateSyntaxError as e:
if settings.DEBUG:
return "[Included template had syntax error: %s]" % e
else:
return '' # Fail silently for invalid included templates.
return output
class LoadNode(Node): class LoadNode(Node):
def render(self, context): def render(self, context):
return '' return ''
...@@ -1091,42 +1052,6 @@ def ifchanged(parser, token): ...@@ -1091,42 +1052,6 @@ def ifchanged(parser, token):
return IfChangedNode(nodelist_true, nodelist_false, *values) return IfChangedNode(nodelist_true, nodelist_false, *values)
@register.tag
def ssi(parser, token):
"""
Outputs the contents of a given file into the page.
Like a simple "include" tag, the ``ssi`` tag includes the contents
of another file -- which must be specified using an absolute path --
in the current page::
{% ssi "/home/html/ljworld.com/includes/right_generic.html" %}
If the optional "parsed" parameter is given, the contents of the included
file are evaluated as template code, with the current context::
{% ssi "/home/html/ljworld.com/includes/right_generic.html" parsed %}
"""
warnings.warn(
"The {% ssi %} tag is deprecated. Use the {% include %} tag instead.",
RemovedInDjango110Warning,
)
bits = token.split_contents()
parsed = False
if len(bits) not in (2, 3):
raise TemplateSyntaxError("'ssi' tag takes one argument: the path to"
" the file to be included")
if len(bits) == 3:
if bits[2] == 'parsed':
parsed = True
else:
raise TemplateSyntaxError("Second (optional) argument to %s tag"
" must be 'parsed'" % bits[0])
filepath = parser.compile_filter(bits[1])
return SsiNode(filepath, parsed)
def find_library(parser, name): def find_library(parser, name):
try: try:
return parser.libraries[name] return parser.libraries[name]
......
...@@ -23,14 +23,11 @@ class Engine(object): ...@@ -23,14 +23,11 @@ class Engine(object):
'django.template.loader_tags', 'django.template.loader_tags',
] ]
def __init__(self, dirs=None, app_dirs=False, def __init__(self, dirs=None, app_dirs=False, context_processors=None,
allowed_include_roots=None, context_processors=None,
debug=False, loaders=None, string_if_invalid='', debug=False, loaders=None, string_if_invalid='',
file_charset='utf-8', libraries=None, builtins=None): file_charset='utf-8', libraries=None, builtins=None):
if dirs is None: if dirs is None:
dirs = [] dirs = []
if allowed_include_roots is None:
allowed_include_roots = []
if context_processors is None: if context_processors is None:
context_processors = [] context_processors = []
if loaders is None: if loaders is None:
...@@ -46,13 +43,8 @@ class Engine(object): ...@@ -46,13 +43,8 @@ class Engine(object):
if builtins is None: if builtins is None:
builtins = [] builtins = []
if isinstance(allowed_include_roots, six.string_types):
raise ImproperlyConfigured(
"allowed_include_roots must be a tuple, not a string.")
self.dirs = dirs self.dirs = dirs
self.app_dirs = app_dirs self.app_dirs = app_dirs
self.allowed_include_roots = allowed_include_roots
self.context_processors = context_processors self.context_processors = context_processors
self.debug = debug self.debug = debug
self.loaders = loaders self.loaders = loaders
......
...@@ -40,7 +40,6 @@ class EngineHandler(object): ...@@ -40,7 +40,6 @@ class EngineHandler(object):
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': settings.TEMPLATE_DIRS, 'DIRS': settings.TEMPLATE_DIRS,
'OPTIONS': { 'OPTIONS': {
'allowed_include_roots': settings.ALLOWED_INCLUDE_ROOTS,
'context_processors': settings.TEMPLATE_CONTEXT_PROCESSORS, 'context_processors': settings.TEMPLATE_CONTEXT_PROCESSORS,
'debug': settings.TEMPLATE_DEBUG, 'debug': settings.TEMPLATE_DEBUG,
'loaders': settings.TEMPLATE_LOADERS, 'loaders': settings.TEMPLATE_LOADERS,
......
...@@ -85,7 +85,6 @@ def reset_template_engines(**kwargs): ...@@ -85,7 +85,6 @@ def reset_template_engines(**kwargs):
if kwargs['setting'] in { if kwargs['setting'] in {
'TEMPLATES', 'TEMPLATES',
'TEMPLATE_DIRS', 'TEMPLATE_DIRS',
'ALLOWED_INCLUDE_ROOTS',
'TEMPLATE_CONTEXT_PROCESSORS', 'TEMPLATE_CONTEXT_PROCESSORS',
'TEMPLATE_DEBUG', 'TEMPLATE_DEBUG',
'TEMPLATE_LOADERS', 'TEMPLATE_LOADERS',
......
...@@ -691,10 +691,10 @@ details on these changes. ...@@ -691,10 +691,10 @@ details on these changes.
handling. (This is faster than the usual deprecation path; see the handling. (This is faster than the usual deprecation path; see the
:doc:`Django 1.4 release notes</releases/1.4>`.) :doc:`Django 1.4 release notes</releases/1.4>`.)
* The :ttag:`url` and :ttag:`ssi` template tags will be * The ``url`` and ``ssi`` template tags will be modified so that the first
modified so that the first argument to each tag is a template variable, not argument to each tag is a template variable, not an implied string. In 1.4,
an implied string. In 1.4, this behavior is provided by a version of the tag this behavior is provided by a version of the tag in the ``future`` template
in the ``future`` template tag library. tag library.
* The ``reset`` and ``sqlreset`` management commands will be removed. * The ``reset`` and ``sqlreset`` management commands will be removed.
......
...@@ -252,9 +252,9 @@ that might occur as a result of a version upgrade. ...@@ -252,9 +252,9 @@ that might occur as a result of a version upgrade.
* **1_8.W001**: The standalone ``TEMPLATE_*`` settings were deprecated in * **1_8.W001**: The standalone ``TEMPLATE_*`` settings were deprecated in
Django 1.8 and the :setting:`TEMPLATES` dictionary takes precedence. You must Django 1.8 and the :setting:`TEMPLATES` dictionary takes precedence. You must
put the values of the following settings into your defaults ``TEMPLATES`` put the values of the following settings into your defaults ``TEMPLATES``
dict: :setting:`TEMPLATE_DIRS`, :setting:`ALLOWED_INCLUDE_ROOTS`, dict: :setting:`TEMPLATE_DIRS`, :setting:`TEMPLATE_CONTEXT_PROCESSORS`,
:setting:`TEMPLATE_CONTEXT_PROCESSORS`, :setting:`TEMPLATE_DEBUG`, :setting:`TEMPLATE_DEBUG`, :setting:`TEMPLATE_LOADERS`,
:setting:`TEMPLATE_LOADERS`, :setting:`TEMPLATE_STRING_IF_INVALID`. :setting:`TEMPLATE_STRING_IF_INVALID`.
Admin Admin
----- -----
......
...@@ -99,32 +99,6 @@ This validation only applies via :meth:`~django.http.HttpRequest.get_host()`; ...@@ -99,32 +99,6 @@ This validation only applies via :meth:`~django.http.HttpRequest.get_host()`;
if your code accesses the ``Host`` header directly from ``request.META`` you if your code accesses the ``Host`` header directly from ``request.META`` you
are bypassing this security protection. are bypassing this security protection.
.. setting:: ALLOWED_INCLUDE_ROOTS
ALLOWED_INCLUDE_ROOTS
---------------------
Default: ``[]`` (Empty list)
.. deprecated:: 1.8
This setting, along with the :ttag:`ssi` template tag, is deprecated and
will be removed in Django 1.10.
.. versionchanged:: 1.8
You can also set the ``'allowed_include_roots'`` option in the
:setting:`OPTIONS <TEMPLATES-OPTIONS>` of a ``DjangoTemplates`` backend
instead.
A list of strings representing allowed prefixes for the ``{% ssi %}`` template
tag. This is a security measure, so that template authors can't access files
that they shouldn't be accessing.
For example, if :setting:`ALLOWED_INCLUDE_ROOTS` is ``['/home/html', '/var/www']``,
then ``{% ssi /home/html/foo.txt %}`` would work, but ``{% ssi /etc/passwd %}``
wouldn't.
.. setting:: APPEND_SLASH .. setting:: APPEND_SLASH
APPEND_SLASH APPEND_SLASH
...@@ -3433,7 +3407,6 @@ Serialization ...@@ -3433,7 +3407,6 @@ Serialization
Templates Templates
--------- ---------
* :setting:`ALLOWED_INCLUDE_ROOTS`
* :setting:`TEMPLATES` * :setting:`TEMPLATES`
* :setting:`TEMPLATE_CONTEXT_PROCESSORS` * :setting:`TEMPLATE_CONTEXT_PROCESSORS`
* :setting:`TEMPLATE_DEBUG` * :setting:`TEMPLATE_DEBUG`
......
...@@ -48,7 +48,7 @@ probably isn't the documentation you're looking for. An instance of the ...@@ -48,7 +48,7 @@ probably isn't the documentation you're looking for. An instance of the
of that backend and any attribute defaults mentioned below are overridden by of that backend and any attribute defaults mentioned below are overridden by
what's passed by :class:`~django.template.backends.django.DjangoTemplates`. what's passed by :class:`~django.template.backends.django.DjangoTemplates`.
.. class:: Engine(dirs=None, app_dirs=False, allowed_include_roots=None, context_processors=None, debug=False, loaders=None, string_if_invalid='', file_charset='utf-8', libraries=None, builtins=None) .. class:: Engine(dirs=None, app_dirs=False, context_processors=None, debug=False, loaders=None, string_if_invalid='', file_charset='utf-8', libraries=None, builtins=None)
.. versionadded:: 1.8 .. versionadded:: 1.8
...@@ -65,21 +65,6 @@ what's passed by :class:`~django.template.backends.django.DjangoTemplates`. ...@@ -65,21 +65,6 @@ what's passed by :class:`~django.template.backends.django.DjangoTemplates`.
It defaults to ``False``. It defaults to ``False``.
* ``allowed_include_roots`` is a list of strings representing allowed
prefixes for the ``{% ssi %}`` template tag. This is a security measure,
so that template authors can't access files that they shouldn't be
accessing.
For example, if ``'allowed_include_roots'`` is ``['/home/html',
'/var/www']``, then ``{% ssi /home/html/foo.txt %}`` would work, but ``{%
ssi /etc/passwd %}`` wouldn't.
It defaults to an empty list.
.. deprecated:: 1.8
``allowed_include_roots`` is deprecated.
* ``context_processors`` is a list of dotted Python paths to callables * ``context_processors`` is a list of dotted Python paths to callables
that are used to populate the context when a template is rendered with a that are used to populate the context when a template is rendered with a
request. These callables take a request object as their argument and request. These callables take a request object as their argument and
......
...@@ -958,45 +958,6 @@ this example, the space around ``Hello`` won't be stripped:: ...@@ -958,45 +958,6 @@ this example, the space around ``Hello`` won't be stripped::
</strong> </strong>
{% endspaceless %} {% endspaceless %}
.. templatetag:: ssi
ssi
^^^
.. deprecated:: 1.8
This tag has been deprecated and will be removed in Django 1.10. Use the
:ttag:`include` tag instead.
Outputs the contents of a given file into the page.
Like a simple :ttag:`include` tag, ``{% ssi %}`` includes the contents of
another file -- which must be specified using an absolute path -- in the
current page::
{% ssi '/home/html/ljworld.com/includes/right_generic.html' %}
The first parameter of ``ssi`` can be a quoted literal or any other context
variable.
If the optional ``parsed`` parameter is given, the contents of the included
file are evaluated as template code, within the current context::
{% ssi '/home/html/ljworld.com/includes/right_generic.html' parsed %}
Note that if you use ``{% ssi %}``, you'll need to define
``'allowed_include_roots'`` in the :setting:`OPTIONS <TEMPLATES-OPTIONS>` of
your template engine, as a security measure.
.. note::
With the :ttag:`ssi` tag and the ``parsed`` parameter
there is no shared state between files -- each include is a completely
independent rendering process. This means it's not possible for example to
define blocks or alter the context in the current page using the included
file.
See also: :ttag:`{% include %}<include>`.
.. templatetag:: templatetag .. templatetag:: templatetag
templatetag templatetag
......
...@@ -730,8 +730,8 @@ and Ctrl-C test termination) have been made redundant. In view of this ...@@ -730,8 +730,8 @@ and Ctrl-C test termination) have been made redundant. In view of this
redundancy, ``DjangoTestRunner`` has been turned into an empty placeholder redundancy, ``DjangoTestRunner`` has been turned into an empty placeholder
class, and will be removed entirely in Django 1.5. class, and will be removed entirely in Django 1.5.
Changes to :ttag:`url` and :ttag:`ssi` Changes to ``url`` and ``ssi``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Most template tags will allow you to pass in either constants or Most template tags will allow you to pass in either constants or
variables as arguments -- for example:: variables as arguments -- for example::
...@@ -745,15 +745,14 @@ context variable ``templ`` that contains the value ``base.html``:: ...@@ -745,15 +745,14 @@ context variable ``templ`` that contains the value ``base.html``::
is also legal. is also legal.
However, due to an accident of history, the :ttag:`url` and However, due to an accident of history, the ``url`` and ``ssi`` are different.
:ttag:`ssi` are different. These tags use the second, quoteless These tags use the second, quoteless syntax, but interpret the argument as a
syntax, but interpret the argument as a constant. This means it isn't constant. This means it isn't possible to use a context variable as the target
possible to use a context variable as the target of a :ttag:`url` and of a ``url`` and ``ssi`` tag.
:ttag:`ssi` tag.
Django 1.3 marks the start of the process to correct this historical Django 1.3 marks the start of the process to correct this historical
accident. Django 1.3 adds a new template library -- ``future`` -- that accident. Django 1.3 adds a new template library -- ``future`` -- that
provides alternate implementations of the :ttag:`url` and :ttag:`ssi` provides alternate implementations of the ``url`` and ``ssi``
template tags. This ``future`` library implement behavior that makes template tags. This ``future`` library implement behavior that makes
the handling of the first argument consistent with the handling of all the handling of the first argument consistent with the handling of all
other variables. So, an existing template that contains:: other variables. So, an existing template that contains::
......
...@@ -7,11 +7,11 @@ Django 1.4.7 release notes ...@@ -7,11 +7,11 @@ Django 1.4.7 release notes
Django 1.4.7 fixes one security issue present in previous Django releases in Django 1.4.7 fixes one security issue present in previous Django releases in
the 1.4 series. the 1.4 series.
Directory traversal vulnerability in :ttag:`ssi` template tag Directory traversal vulnerability in ``ssi`` template tag
------------------------------------------------------------- ---------------------------------------------------------
In previous versions of Django it was possible to bypass the In previous versions of Django it was possible to bypass the
:setting:`ALLOWED_INCLUDE_ROOTS` setting used for security with the :ttag:`ssi` ``ALLOWED_INCLUDE_ROOTS`` setting used for security with the ``ssi``
template tag by specifying a relative path that starts with one of the allowed template tag by specifying a relative path that starts with one of the allowed
roots. For example, if ``ALLOWED_INCLUDE_ROOTS = ("/var/www",)`` the following roots. For example, if ``ALLOWED_INCLUDE_ROOTS = ("/var/www",)`` the following
would be possible: would be possible:
...@@ -21,5 +21,5 @@ would be possible: ...@@ -21,5 +21,5 @@ would be possible:
{% ssi "/var/www/../../etc/passwd" %} {% ssi "/var/www/../../etc/passwd" %}
In practice this is not a very common problem, as it would require the template In practice this is not a very common problem, as it would require the template
author to put the :ttag:`ssi` file in a user-controlled variable, but it's author to put the ``ssi`` file in a user-controlled variable, but it's
possible in principle. possible in principle.
...@@ -8,11 +8,11 @@ This is Django 1.5.3, the third release in the Django 1.5 series. It addresses ...@@ -8,11 +8,11 @@ This is Django 1.5.3, the third release in the Django 1.5 series. It addresses
one security issue and also contains an opt-in feature to enhance the security one security issue and also contains an opt-in feature to enhance the security
of :mod:`django.contrib.sessions`. of :mod:`django.contrib.sessions`.
Directory traversal vulnerability in :ttag:`ssi` template tag Directory traversal vulnerability in ``ssi`` template tag
------------------------------------------------------------- ---------------------------------------------------------
In previous versions of Django it was possible to bypass the In previous versions of Django it was possible to bypass the
:setting:`ALLOWED_INCLUDE_ROOTS` setting used for security with the :ttag:`ssi` ``ALLOWED_INCLUDE_ROOTS`` setting used for security with the ``ssi``
template tag by specifying a relative path that starts with one of the allowed template tag by specifying a relative path that starts with one of the allowed
roots. For example, if ``ALLOWED_INCLUDE_ROOTS = ("/var/www",)`` the following roots. For example, if ``ALLOWED_INCLUDE_ROOTS = ("/var/www",)`` the following
would be possible: would be possible:
...@@ -22,8 +22,8 @@ would be possible: ...@@ -22,8 +22,8 @@ would be possible:
{% ssi "/var/www/../../etc/passwd" %} {% ssi "/var/www/../../etc/passwd" %}
In practice this is not a very common problem, as it would require the template In practice this is not a very common problem, as it would require the template
author to put the :ttag:`ssi` file in a user-controlled variable, but it's author to put the ``ssi`` file in a user-controlled variable, but it's possible
possible in principle. in principle.
Mitigating a remote-code execution vulnerability in :mod:`django.contrib.sessions` Mitigating a remote-code execution vulnerability in :mod:`django.contrib.sessions`
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
......
...@@ -1734,7 +1734,7 @@ Loading ``ssi`` and ``url`` template tags from ``future`` library ...@@ -1734,7 +1734,7 @@ Loading ``ssi`` and ``url`` template tags from ``future`` library
Django 1.3 introduced ``{% load ssi from future %}`` and Django 1.3 introduced ``{% load ssi from future %}`` and
``{% load url from future %}`` syntax for forward compatibility of the ``{% load url from future %}`` syntax for forward compatibility of the
:ttag:`ssi` and :ttag:`url` template tags. This syntax is now deprecated and ``ssi`` and :ttag:`url` template tags. This syntax is now deprecated and
will be removed in Django 1.9. You can simply remove the will be removed in Django 1.9. You can simply remove the
``{% load ... from future %}`` tags. ``{% load ... from future %}`` tags.
......
...@@ -1654,7 +1654,7 @@ Django 1.10. ...@@ -1654,7 +1654,7 @@ Django 1.10.
``ssi`` template tag ``ssi`` template tag
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
The :ttag:`ssi` template tag allows files to be included in a template by The ``ssi`` template tag allows files to be included in a template by
absolute path. This is of limited use in most deployment situations, and absolute path. This is of limited use in most deployment situations, and
the :ttag:`include` tag often makes more sense. This tag is now deprecated and the :ttag:`include` tag often makes more sense. This tag is now deprecated and
will be removed in Django 1.10. will be removed in Django 1.10.
......
...@@ -348,21 +348,6 @@ applications. This generic name was kept for backwards-compatibility. ...@@ -348,21 +348,6 @@ applications. This generic name was kept for backwards-compatibility.
``DjangoTemplates`` engines accept the following :setting:`OPTIONS ``DjangoTemplates`` engines accept the following :setting:`OPTIONS
<TEMPLATES-OPTIONS>`: <TEMPLATES-OPTIONS>`:
* ``'allowed_include_roots'``: a list of strings representing allowed prefixes
for the ``{% ssi %}`` template tag. This is a security measure, so that
template authors can't access files that they shouldn't be accessing.
For example, if ``'allowed_include_roots'`` is ``['/home/html',
'/var/www']``, then ``{% ssi /home/html/foo.txt %}`` would work, but ``{%
ssi /etc/passwd %}`` wouldn't.
It defaults to an empty list.
.. deprecated:: 1.8
``allowed_include_roots`` is deprecated because the {% ssi %} tag is
deprecated.
* ``'context_processors'``: a list of dotted Python paths to callables that * ``'context_processors'``: a list of dotted Python paths to callables that
are used to populate the context when a template is rendered with a request. are used to populate the context when a template is rendered with a request.
These callables take a request object as their argument and return a These callables take a request object as their argument and return a
......
...@@ -472,7 +472,6 @@ class TestListSettings(unittest.TestCase): ...@@ -472,7 +472,6 @@ class TestListSettings(unittest.TestCase):
ImproperlyConfigured if they are set to a string instead of a list or tuple. ImproperlyConfigured if they are set to a string instead of a list or tuple.
""" """
list_or_tuple_settings = ( list_or_tuple_settings = (
"ALLOWED_INCLUDE_ROOTS",
"INSTALLED_APPS", "INSTALLED_APPS",
"TEMPLATE_DIRS", "TEMPLATE_DIRS",
"LOCALE_PATHS", "LOCALE_PATHS",
......
from __future__ import unicode_literals
import os
from django.template import Context, Engine
from django.test import SimpleTestCase, ignore_warnings
from django.utils.deprecation import RemovedInDjango110Warning
from ..utils import ROOT, setup
@ignore_warnings(category=RemovedInDjango110Warning)
class SsiTagTests(SimpleTestCase):
# Test normal behavior
@setup({'ssi01': '{%% ssi "%s" %%}' % os.path.join(
ROOT, 'templates', 'ssi_include.html',
)})
def test_ssi01(self):
output = self.engine.render_to_string('ssi01')
self.assertEqual(output, 'This is for testing an ssi include. {{ test }}\n')
@setup({'ssi02': '{%% ssi "%s" %%}' % os.path.join(
ROOT, 'not_here',
)})
def test_ssi02(self):
output = self.engine.render_to_string('ssi02')
self.assertEqual(output, ''),
@setup({'ssi03': "{%% ssi '%s' %%}" % os.path.join(
ROOT, 'not_here',
)})
def test_ssi03(self):
output = self.engine.render_to_string('ssi03')
self.assertEqual(output, ''),
# Test passing as a variable
@setup({'ssi04': '{% ssi ssi_file %}'})
def test_ssi04(self):
output = self.engine.render_to_string('ssi04', {
'ssi_file': os.path.join(ROOT, 'templates', 'ssi_include.html')
})
self.assertEqual(output, 'This is for testing an ssi include. {{ test }}\n')
@setup({'ssi05': '{% ssi ssi_file %}'})
def test_ssi05(self):
output = self.engine.render_to_string('ssi05', {'ssi_file': 'no_file'})
self.assertEqual(output, '')
# Test parsed output
@setup({'ssi06': '{%% ssi "%s" parsed %%}' % os.path.join(
ROOT, 'templates', 'ssi_include.html',
)})
def test_ssi06(self):
output = self.engine.render_to_string('ssi06', {'test': 'Look ma! It parsed!'})
self.assertEqual(output, 'This is for testing an ssi include. '
'Look ma! It parsed!\n')
@setup({'ssi07': '{%% ssi "%s" parsed %%}' % os.path.join(
ROOT, 'not_here',
)})
def test_ssi07(self):
output = self.engine.render_to_string('ssi07', {'test': 'Look ma! It parsed!'})
self.assertEqual(output, '')
# Test space in file name
@setup({'ssi08': '{%% ssi "%s" %%}' % os.path.join(
ROOT, 'templates', 'ssi include with spaces.html',
)})
def test_ssi08(self):
output = self.engine.render_to_string('ssi08')
self.assertEqual(output, 'This is for testing an ssi include '
'with spaces in its name. {{ test }}\n')
@setup({'ssi09': '{%% ssi "%s" parsed %%}' % os.path.join(
ROOT, 'templates', 'ssi include with spaces.html',
)})
def test_ssi09(self):
output = self.engine.render_to_string('ssi09', {'test': 'Look ma! It parsed!'})
self.assertEqual(output, 'This is for testing an ssi include '
'with spaces in its name. Look ma! It parsed!\n')
@ignore_warnings(category=RemovedInDjango110Warning)
class SSISecurityTests(SimpleTestCase):
def setUp(self):
self.ssi_dir = os.path.join(ROOT, "templates", "first")
self.engine = Engine(allowed_include_roots=(self.ssi_dir,))
def render_ssi(self, path):
# the path must exist for the test to be reliable
self.assertTrue(os.path.exists(path))
return self.engine.from_string('{%% ssi "%s" %%}' % path).render(Context({}))
def test_allowed_paths(self):
acceptable_path = os.path.join(self.ssi_dir, "..", "first", "test.html")
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"),
]
for disallowed_path in disallowed_paths:
self.assertEqual(self.render_ssi(disallowed_path), '')
...@@ -55,7 +55,6 @@ def setup(templates, *args, **kwargs): ...@@ -55,7 +55,6 @@ def setup(templates, *args, **kwargs):
libraries = getattr(self, 'libraries', {}) libraries = getattr(self, 'libraries', {})
self.engine = Engine( self.engine = Engine(
allowed_include_roots=[ROOT],
libraries=libraries, libraries=libraries,
loaders=loaders, loaders=loaders,
) )
...@@ -65,7 +64,6 @@ def setup(templates, *args, **kwargs): ...@@ -65,7 +64,6 @@ def setup(templates, *args, **kwargs):
func(self) func(self)
self.engine = Engine( self.engine = Engine(
allowed_include_roots=[ROOT],
libraries=libraries, libraries=libraries,
loaders=loaders, loaders=loaders,
string_if_invalid='INVALID', string_if_invalid='INVALID',
...@@ -74,7 +72,6 @@ def setup(templates, *args, **kwargs): ...@@ -74,7 +72,6 @@ def setup(templates, *args, **kwargs):
func(self) func(self)
self.engine = Engine( self.engine = Engine(
allowed_include_roots=[ROOT],
debug=True, debug=True,
libraries=libraries, libraries=libraries,
loaders=loaders, loaders=loaders,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment