Песочница
Песочница Jinja может использоваться для оценки небезопасного кода. Доступ к небезопасным атрибутам и методам запрещён.
Предполагая, что env является SandboxedEnvironment в конфигурации по умолчанию, следующий фрагмент кода демонстрирует, как это работает:
>>> env.from_string("{{ func.func_code }}").render(func=lambda:None)
u''
>>> env.from_string("{{ func.func_code.do_something }}").render(func=lambda:None)
Traceback (most recent call last):
...
SecurityError: access to attribute 'func_code' of 'function' object is unsafe.
API
-
class jinja2.sandbox.SandboxedEnvironment([options]) -
Песочница для окружения. Она работает как обычное окружение, но сообщает компилятору сгенерировать код в песочнице. Кроме того, подклассы этого окружения могут переопределять методы, которые сообщают исполняемой среде, какие атрибуты или функции безопасно использовать.
Если шаблон пытается получить доступ к небезопасному коду, возникает
SecurityError. Однако могут произойти и другие исключения во время рендеринга, поэтому вызывающий код должен убедиться, что все исключения перехватываются.-
call_binop(context, operator, left, right) -
Для перехваченных бинарных операций (
intercepted_binops()) эта функция выполняется вместо встроенной операции. Это можно использовать для тонкой настройки поведения определенных операций.Changelog
Новая в версии 2.6.
-
call_unop(context, operator, arg) -
Для перехваченных унарных операций (
intercepted_unops()) эта функция выполняется вместо встроенной операции. Это можно использовать для тонкой настройки поведения определенных операций.Changelog
Новая в версии 2.6.
-
default_binop_table = {'%': <built-in function mod>, '*': <built-in function mul>, '**': <built-in function pow>, '+': <built-in function add>, '-': <built-in function sub>, '/': <built-in function truediv>, '//': <built-in function floordiv>} -
Таблицы обратных вызовов для бинарных операций по умолчанию. Копия доступна в каждом экземпляре среды песочницы как
binop_table
-
default_unop_table = {'+': <built-in function pos>, '-': <built-in function neg>} -
Таблицы обратных вызовов для унарных операций по умолчанию. Копия доступна в каждом экземпляре среды песочницы как
unop_table
-
intercepted_binops = frozenset({}) -
Набор бинарных операций, которые должны быть перехвачены. Каждая операция, добавленная в этот набор (пустой по умолчанию), делегируется методу
call_binop(), который выполнит операцию. Обратный вызов по умолчанию для операции задаетсяbinop_table.Следующие бинарные операции могут быть перехвачены:
//,%,+,*,-,/, и**По умолчанию операция из таблицы соответствует встроенной функции. Перехваченные вызовы всегда медленнее, чем вызов родной операции, поэтому убедитесь, что перехватываете только те, которые вам нужны.
Changelog
Новая в версии 2.6.
-
intercepted_unops = frozenset({}) -
Набор унарных операций, которые должны быть перехвачены. Каждая операция, добавленная в этот набор (пустой по умолчанию), делегируется методу
call_unop(), который выполнит операцию. Обратный вызов по умолчанию для операции задаетсяunop_table.Следующие унарные операции могут быть перехвачены:
+,-По умолчанию операция из таблицы соответствует встроенной функции. Перехваченные вызовы всегда медленнее, чем вызов родной операции, поэтому убедитесь, что перехватываете только те, которые вам нужны.
Changelog
Новая в версии 2.6.
-
is_safe_attribute(obj, attr, value) -
Песочница будет вызывать этот метод, чтобы проверить, безопасно ли получить доступ к атрибуту объекта. По умолчанию все атрибуты, начинающиеся с подчеркивания, считаются приватными, а также специальные атрибуты внутренних объектов Python, возвращаемые функцией
is_internal_attribute().
-
is_safe_callable(obj) -
Проверить, можно ли безопасно вызвать объект. По умолчанию функция считается безопасной, если атрибут
unsafe_callableсуществует и равен True. Переопределите этот метод, чтобы изменить поведение, но это не повлияет на декораторunsafeиз этого модуля.
-
-
class jinja2.sandbox.ImmutableSandboxedEnvironment([options]) -
Работает точно так же, как и обычный
SandboxedEnvironment, но не позволяет изменять встроенные изменяемые объектыlist,set, иdictс помощью функцииmodifies_known_mutable().
-
exception jinja2.sandbox.SecurityError(message=None) -
Вызывается, если шаблон пытается выполнить небезопасное действие, если включён режим песочницы.
-
jinja2.sandbox.unsafe(f) -
Помечает функцию или метод как небезопасный.
@unsafe def delete(self): pass
-
jinja2.sandbox.is_internal_attribute(obj, attr) -
Проверяет, является ли заданный атрибут внутренним атрибутом Python. Например, эта функция возвращает
Trueдля атрибутаfunc_codeобъектов Python. Это полезно, если переопределяется метод средыis_safe_attribute().>>> from jinja2.sandbox import is_internal_attribute >>> is_internal_attribute(str, "mro") True >>> is_internal_attribute(str, "upper") False
-
jinja2.sandbox.modifies_known_mutable(obj, attr) -
Эта функция проверяет, изменит ли вызов атрибута встроенного изменяемого объекта (списка, словаря, множества или очереди) его. Она также поддерживает «пользовательские» версии объектов (
sets.Set,UserDict.*и т. д.) и начиная с Python 2.6 абстрактные базовые классыMutableSet,MutableMapping, иMutableSequence.>>> modifies_known_mutable({}, "clear") True >>> modifies_known_mutable({}, "keys") False >>> modifies_known_mutable([], "append") True >>> modifies_known_mutable([], "index") FalseЕсли вызов происходит с неподдерживаемым объектом (например, unicode), возвращается
False.>>> modifies_known_mutable("foo", "upper") False
Примечание
Только песочница Jinja не является решением для абсолютной безопасности. Особенно для веб-приложений необходимо учитывать, что пользователи могут создавать шаблоны с произвольным HTML, поэтому крайне важно гарантировать, что (если вы запускаете нескольких пользователей на одном сервере) они не смогут причинить вред друг другу через вставки JavaScript и многое другое.
Кроме того, песочница эффективна только в той мере, в какой она настроена. Мы настоятельно рекомендуем передавать в шаблон только неразделяемые ресурсы и использовать некий вид белого списка для атрибутов.
Также следует учитывать, что шаблоны могут вызывать ошибки во время выполнения или компиляции, поэтому необходимо их перехватывать.
Перехват операторов
Изменения
Введено в версии 2.6.
Для максимальной производительности Jinja позволит операторам непосредственно вызывать методы, специфичные для типа. Это означает, что перехват с помощью переопределения Environment.call() невозможен. Кроме того, преобразование оператора в специальный метод не всегда возможно напрямую из-за принципов работы операторов. Например, для деления существует более одного специального метода.
В Jinja 2.6 появилась поддержка явного перехвата операторов. Это можно использовать для настройки конкретных операторов по необходимости. Чтобы перехватить оператор, необходимо переопределить атрибут SandboxedEnvironment.intercepted_binops. После добавления оператора, который необходимо перехватить, в этот набор Jinja сгенерирует байт-код, вызывающий функцию SandboxedEnvironment.call_binop(). Для унарных операторов следует использовать атрибуты и методы unary.
В реализации по умолчанию SandboxedEnvironment.call_binop будет использоваться SandboxedEnvironment.binop_table для преобразования символов операторов в вызовы, выполняющие поведение операторов по умолчанию.
В этом примере показано, как можно отключить оператор «сила» (**):
from jinja2.sandbox import SandboxedEnvironment
class MyEnvironment(SandboxedEnvironment):
intercepted_binops = frozenset(['**'])
def call_binop(self, context, operator, left, right):
if operator == '**':
return self.undefined('the power operator is unavailable')
return SandboxedEnvironment.call_binop(self, context,
operator, left, right)
Убедитесь, что всегда вызывается метод super(), даже если вы не перехватываете вызов. Jinja может внутренне вызвать метод для оценки выражений.
© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://jinja.palletsprojects.com/en/2.11.x/sandbox/