mirror of
https://github.com/django/django.git
synced 2025-01-19 06:43:15 +00:00
Refs #24022 -- Removed the ssi tag per deprecation timeline.
This commit is contained in:
parent
3af9b70028
commit
04ee4059d7
@ -99,7 +99,6 @@ class Settings(BaseSettings):
|
||||
mod = importlib.import_module(self.SETTINGS_MODULE)
|
||||
|
||||
tuple_settings = (
|
||||
"ALLOWED_INCLUDE_ROOTS",
|
||||
"INSTALLED_APPS",
|
||||
"TEMPLATE_DIRS",
|
||||
"LOCALE_PATHS",
|
||||
|
@ -260,10 +260,6 @@ DISALLOWED_USER_AGENTS = []
|
||||
|
||||
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
|
||||
# be reported by BrokenLinkEmailsMiddleware. Here are a few examples:
|
||||
# import re
|
||||
|
@ -10,7 +10,6 @@ def check_duplicate_template_settings(app_configs, **kwargs):
|
||||
if settings.TEMPLATES:
|
||||
values = [
|
||||
'TEMPLATE_DIRS',
|
||||
'ALLOWED_INCLUDE_ROOTS',
|
||||
'TEMPLATE_CONTEXT_PROCESSORS',
|
||||
'TEMPLATE_DEBUG',
|
||||
'TEMPLATE_LOADERS',
|
||||
|
@ -1,7 +1,6 @@
|
||||
"""Default tags used by the template system, available to all templates."""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import warnings
|
||||
@ -19,7 +18,7 @@ from django.utils.safestring import mark_safe
|
||||
from .base import (
|
||||
BLOCK_TAG_END, BLOCK_TAG_START, COMMENT_TAG_END, COMMENT_TAG_START,
|
||||
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,
|
||||
render_value_in_context, token_kwargs,
|
||||
)
|
||||
@ -373,44 +372,6 @@ class RegroupNode(Node):
|
||||
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):
|
||||
def render(self, context):
|
||||
return ''
|
||||
@ -1091,42 +1052,6 @@ def ifchanged(parser, token):
|
||||
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):
|
||||
try:
|
||||
return parser.libraries[name]
|
||||
|
@ -23,14 +23,11 @@ class Engine(object):
|
||||
'django.template.loader_tags',
|
||||
]
|
||||
|
||||
def __init__(self, dirs=None, app_dirs=False,
|
||||
allowed_include_roots=None, context_processors=None,
|
||||
def __init__(self, dirs=None, app_dirs=False, context_processors=None,
|
||||
debug=False, loaders=None, string_if_invalid='',
|
||||
file_charset='utf-8', libraries=None, builtins=None):
|
||||
if dirs is None:
|
||||
dirs = []
|
||||
if allowed_include_roots is None:
|
||||
allowed_include_roots = []
|
||||
if context_processors is None:
|
||||
context_processors = []
|
||||
if loaders is None:
|
||||
@ -46,13 +43,8 @@ class Engine(object):
|
||||
if builtins is None:
|
||||
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.app_dirs = app_dirs
|
||||
self.allowed_include_roots = allowed_include_roots
|
||||
self.context_processors = context_processors
|
||||
self.debug = debug
|
||||
self.loaders = loaders
|
||||
|
@ -40,7 +40,6 @@ class EngineHandler(object):
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': settings.TEMPLATE_DIRS,
|
||||
'OPTIONS': {
|
||||
'allowed_include_roots': settings.ALLOWED_INCLUDE_ROOTS,
|
||||
'context_processors': settings.TEMPLATE_CONTEXT_PROCESSORS,
|
||||
'debug': settings.TEMPLATE_DEBUG,
|
||||
'loaders': settings.TEMPLATE_LOADERS,
|
||||
|
@ -85,7 +85,6 @@ def reset_template_engines(**kwargs):
|
||||
if kwargs['setting'] in {
|
||||
'TEMPLATES',
|
||||
'TEMPLATE_DIRS',
|
||||
'ALLOWED_INCLUDE_ROOTS',
|
||||
'TEMPLATE_CONTEXT_PROCESSORS',
|
||||
'TEMPLATE_DEBUG',
|
||||
'TEMPLATE_LOADERS',
|
||||
|
@ -691,10 +691,10 @@ details on these changes.
|
||||
handling. (This is faster than the usual deprecation path; see the
|
||||
:doc:`Django 1.4 release notes</releases/1.4>`.)
|
||||
|
||||
* The :ttag:`url` and :ttag:`ssi` template tags will be
|
||||
modified so that the first argument to each tag is a template variable, not
|
||||
an implied string. In 1.4, this behavior is provided by a version of the tag
|
||||
in the ``future`` template tag library.
|
||||
* The ``url`` and ``ssi`` template tags will be modified so that the first
|
||||
argument to each tag is a template variable, not an implied string. In 1.4,
|
||||
this behavior is provided by a version of the tag in the ``future`` template
|
||||
tag library.
|
||||
|
||||
* The ``reset`` and ``sqlreset`` management commands will be removed.
|
||||
|
||||
|
@ -252,9 +252,9 @@ that might occur as a result of a version upgrade.
|
||||
* **1_8.W001**: The standalone ``TEMPLATE_*`` settings were deprecated in
|
||||
Django 1.8 and the :setting:`TEMPLATES` dictionary takes precedence. You must
|
||||
put the values of the following settings into your defaults ``TEMPLATES``
|
||||
dict: :setting:`TEMPLATE_DIRS`, :setting:`ALLOWED_INCLUDE_ROOTS`,
|
||||
:setting:`TEMPLATE_CONTEXT_PROCESSORS`, :setting:`TEMPLATE_DEBUG`,
|
||||
:setting:`TEMPLATE_LOADERS`, :setting:`TEMPLATE_STRING_IF_INVALID`.
|
||||
dict: :setting:`TEMPLATE_DIRS`, :setting:`TEMPLATE_CONTEXT_PROCESSORS`,
|
||||
:setting:`TEMPLATE_DEBUG`, :setting:`TEMPLATE_LOADERS`,
|
||||
:setting:`TEMPLATE_STRING_IF_INVALID`.
|
||||
|
||||
Admin
|
||||
-----
|
||||
|
@ -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
|
||||
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
|
||||
|
||||
APPEND_SLASH
|
||||
@ -3433,7 +3407,6 @@ Serialization
|
||||
|
||||
Templates
|
||||
---------
|
||||
* :setting:`ALLOWED_INCLUDE_ROOTS`
|
||||
* :setting:`TEMPLATES`
|
||||
* :setting:`TEMPLATE_CONTEXT_PROCESSORS`
|
||||
* :setting:`TEMPLATE_DEBUG`
|
||||
|
@ -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
|
||||
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
|
||||
|
||||
@ -65,21 +65,6 @@ what's passed by :class:`~django.template.backends.django.DjangoTemplates`.
|
||||
|
||||
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
|
||||
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
|
||||
|
@ -958,45 +958,6 @@ this example, the space around ``Hello`` won't be stripped::
|
||||
</strong>
|
||||
{% 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
|
||||
|
@ -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
|
||||
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
|
||||
variables as arguments -- for example::
|
||||
@ -745,15 +745,14 @@ context variable ``templ`` that contains the value ``base.html``::
|
||||
|
||||
is also legal.
|
||||
|
||||
However, due to an accident of history, the :ttag:`url` and
|
||||
:ttag:`ssi` are different. These tags use the second, quoteless
|
||||
syntax, but interpret the argument as a constant. This means it isn't
|
||||
possible to use a context variable as the target of a :ttag:`url` and
|
||||
:ttag:`ssi` tag.
|
||||
However, due to an accident of history, the ``url`` and ``ssi`` are different.
|
||||
These tags use the second, quoteless syntax, but interpret the argument as a
|
||||
constant. This means it isn't possible to use a context variable as the target
|
||||
of a ``url`` and ``ssi`` tag.
|
||||
|
||||
Django 1.3 marks the start of the process to correct this historical
|
||||
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
|
||||
the handling of the first argument consistent with the handling of all
|
||||
other variables. So, an existing template that contains::
|
||||
|
@ -7,11 +7,11 @@ Django 1.4.7 release notes
|
||||
Django 1.4.7 fixes one security issue present in previous Django releases in
|
||||
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
|
||||
: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
|
||||
roots. For example, if ``ALLOWED_INCLUDE_ROOTS = ("/var/www",)`` the following
|
||||
would be possible:
|
||||
@ -21,5 +21,5 @@ would be possible:
|
||||
{% ssi "/var/www/../../etc/passwd" %}
|
||||
|
||||
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.
|
||||
|
@ -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
|
||||
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
|
||||
: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
|
||||
roots. For example, if ``ALLOWED_INCLUDE_ROOTS = ("/var/www",)`` the following
|
||||
would be possible:
|
||||
@ -22,8 +22,8 @@ would be possible:
|
||||
{% ssi "/var/www/../../etc/passwd" %}
|
||||
|
||||
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
|
||||
possible in principle.
|
||||
author to put the ``ssi`` file in a user-controlled variable, but it's possible
|
||||
in principle.
|
||||
|
||||
Mitigating a remote-code execution vulnerability in :mod:`django.contrib.sessions`
|
||||
----------------------------------------------------------------------------------
|
||||
|
@ -1734,7 +1734,7 @@ Loading ``ssi`` and ``url`` template tags from ``future`` library
|
||||
|
||||
Django 1.3 introduced ``{% load ssi from future %}`` and
|
||||
``{% 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
|
||||
``{% load ... from future %}`` tags.
|
||||
|
||||
|
@ -1654,7 +1654,7 @@ Django 1.10.
|
||||
``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
|
||||
the :ttag:`include` tag often makes more sense. This tag is now deprecated and
|
||||
will be removed in Django 1.10.
|
||||
|
@ -348,21 +348,6 @@ applications. This generic name was kept for backwards-compatibility.
|
||||
``DjangoTemplates`` engines accept the following :setting:`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
|
||||
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
|
||||
|
@ -472,7 +472,6 @@ class TestListSettings(unittest.TestCase):
|
||||
ImproperlyConfigured if they are set to a string instead of a list or tuple.
|
||||
"""
|
||||
list_or_tuple_settings = (
|
||||
"ALLOWED_INCLUDE_ROOTS",
|
||||
"INSTALLED_APPS",
|
||||
"TEMPLATE_DIRS",
|
||||
"LOCALE_PATHS",
|
||||
|
@ -1,112 +0,0 @@
|
||||
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):
|
||||
libraries = getattr(self, 'libraries', {})
|
||||
|
||||
self.engine = Engine(
|
||||
allowed_include_roots=[ROOT],
|
||||
libraries=libraries,
|
||||
loaders=loaders,
|
||||
)
|
||||
@ -65,7 +64,6 @@ def setup(templates, *args, **kwargs):
|
||||
func(self)
|
||||
|
||||
self.engine = Engine(
|
||||
allowed_include_roots=[ROOT],
|
||||
libraries=libraries,
|
||||
loaders=loaders,
|
||||
string_if_invalid='INVALID',
|
||||
@ -74,7 +72,6 @@ def setup(templates, *args, **kwargs):
|
||||
func(self)
|
||||
|
||||
self.engine = Engine(
|
||||
allowed_include_roots=[ROOT],
|
||||
debug=True,
|
||||
libraries=libraries,
|
||||
loaders=loaders,
|
||||
|
Loading…
x
Reference in New Issue
Block a user