Spec-Zone.ru › Jinja 2.10

Песочница

Песочница Jinja2 может быть использована для оценки небезопасного кода. Доступ к небезопасным атрибутам и методам запрещён.

Предполагая, что 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

Примечание

Песочница Jinja2 сама по себе не является решением для абсолютной безопасности. Особенно для веб-приложений необходимо учитывать, что пользователи могут создавать шаблоны с произвольным HTML, поэтому крайне важно гарантировать, что (если на одном сервере работают несколько пользователей) они не смогут навредить друг другу с помощью вставок JavaScript и т. д.

Также песочница эффективна только в соответствии с настройками. Мы настоятельно рекомендуем передавать шаблонам только неразделяемые ресурсы и использовать какой-либо вид белого списка для атрибутов.

Также следует помнить, что шаблоны могут генерировать ошибки во время выполнения или компиляции, поэтому необходимо перехватывать их.

Перехват операторов

Изменения

Введено в версии 2.6.

Для максимальной производительности Jinja2 позволяет операторам непосредственно вызывать методы, специфичные для типа. Это означает, что перехват с помощью переопределения Environment.call() невозможен. Кроме того, преобразование оператора в специальный метод не всегда возможно напрямую из-за принципов работы операторов. Например, для деления существует не один специальный метод.

С Jinja 2.6 появилась поддержка явного перехвата операторов. Это позволяет настраивать определённые операторы по мере необходимости. Чтобы перехватить оператор, необходимо переопределить атрибут SandboxedEnvironment.intercepted_binops. После добавления необходимого оператора в этот набор Jinja2 сгенерирует байт-код, вызывающий функцию SandboxedEnvironment.call_binop(). Для унарных операторов необходимо использовать атрибуты и методы unary вместо них.

В реализации по умолчанию SandboxedEnvironment.call_binop используется SandboxedEnvironment.binop_table для преобразования символов операторов в обратные вызовы, выполняющие поведение операторов по умолчанию.

Этот пример показывает, как можно отключить оператор «степень» (**) в Jinja2:

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)

Убедитесь, что вы всегда вызываете метод супер, даже если вы не перехватываете вызов. Jinja2 может внутренне вызвать метод для оценки выражений.

© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://jinja.palletsprojects.com/en/2.10.x/sandbox/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API