Песочница
Песочница 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. Однако также могут возникнуть и другие исключения во время рендеринга, поэтому вызывающая сторона должна гарантировать перехват всех исключений.- Параметры
-
- args (Any) –
- kwargs (Any) –
- Тип возвращаемого значения
-
call_binop(context, operator, left, right) -
Для перехваченных бинарных операторов (
intercepted_binops()) эта функция выполняется вместо встроенного оператора. Это можно использовать для тонкой настройки поведения определённых операторов.Журнал изменений
Новая в версии 2.6.
- Параметры
-
- context (jinja2.runtime.Context) –
- operator (str) –
- left (Any) –
- right (Any) –
- Тип возвращаемого значения
-
Any
-
call_unop(context, operator, arg) -
Для перехваченных унарных операторов (
intercepted_unops()) эта функция выполняется вместо встроенного оператора. Это можно использовать для тонкой настройки поведения определённых операторов.Журнал изменений
Новая в версии 2.6.
- Параметры
-
- context (jinja2.runtime.Context) –
- operator (str) –
- arg (Any) –
- Тип возвращаемого значения
-
Any
-
default_binop_table: Dict[str, Callable[[Any, Any], Any]] = {'%': <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: Dict[str, Callable[[Any], Any]] = {'+': <built-in function pos>, '-': <built-in function neg>} -
Таблица обратных вызовов для унарных операторов по умолчанию. Копия этой таблицы доступна на каждом экземпляре среды песочницы как
unop_table
-
intercepted_binops: FrozenSet[str] = frozenset({}) -
Множество бинарных операторов, которые должны быть перехвачены. Каждый добавленный в это множество оператор (по умолчанию пустое множество) делегируется методу
call_binop(), который выполнит операцию. Обратный вызов по умолчанию для операторов задан вbinop_table.Следующие бинарные операторы могут быть перехвачены:
//,%,+,*,-,/, и**По умолчанию операция из таблицы операторов соответствует встроенной функции. Перехваченные вызовы всегда медленнее, чем вызовы нативных операторов, поэтому убедитесь, что перехватываете только нужные вам операторы.
Журнал изменений
Новая в версии 2.6.
-
intercepted_unops: FrozenSet[str] = frozenset({}) -
Множество унарных операторов, которые должны быть перехвачены. Каждый добавленный в это множество оператор (по умолчанию пустое множество) делегируется методу
call_unop(), который выполнит операцию. Обратный вызов по умолчанию для операторов задан вunop_table.Следующие унарные операторы могут быть перехвачены:
+,-По умолчанию операция из таблицы операторов соответствует встроенной функции. Перехваченные вызовы всегда медленнее, чем вызовы нативных операторов, поэтому убедитесь, что перехватываете только нужные вам операторы.
Журнал изменений
Новая в версии 2.6.
-
is_safe_attribute(obj, attr, value) -
Среда песочницы вызовет этот метод, чтобы проверить, является ли атрибут объекта безопасным для доступа. По умолчанию все атрибуты, начинающиеся с нижнего подчёркивания, считаются приватными, а также специальные атрибуты внутренних объектов Python, как возвращаемые функцией
is_internal_attribute().
-
class jinja2.sandbox.ImmutableSandboxedEnvironment([options]) -
Работает точно так же, как и обычная
SandboxedEnvironmentсреда, но не допускает модификаций встроенных изменяемых объектовlist,set, иdict, используя функциюmodifies_known_mutable().- Параметры
-
- args (Any) –
- kwargs (Any) –
- Тип возвращаемого значения
-
exception jinja2.sandbox.SecurityError(message=None) -
Выбрасывается, если шаблон пытается сделать что-то небезопасное, если песочница включена.
-
jinja2.sandbox.unsafe(f) -
Помечает функцию или метод как небезопасный.
- Параметры
-
f (jinja2.sandbox.F) –
- Тип возвращаемого значения
-
jinja2.sandbox.F
-
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) -
Эта функция проверяет, будет ли вызов атрибута на встроенном изменяемом объекте (список, словарь, множество или deque) или соответствующих ABC изменять его.
>>> modifies_known_mutable({}, "clear") True >>> modifies_known_mutable({}, "keys") False >>> modifies_known_mutable([], "append") True >>> modifies_known_mutable([], "index") FalseЕсли вызывается с неподдерживаемым объектом, возвращается
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 для перевода символов операторов в обратные вызовы, выполняющие стандартное поведение оператора.
Этот пример демонстрирует, как можно отключить оператор «степень» (**) в Jinja:
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)
Убедитесь, что всегда вызывается метод супер, даже если вы не перехватываете вызов. Jinja может внутренне вызвать метод для оценки выражений.
© 2007–2021 Pallets
Licensed under the BSD 3-clause License.
https://jinja.palletsprojects.com/en/3.0.x/sandbox/