Jinja2 filtration bypass

cotsom
1 minute read

Санитизация в jinja2

Начать стоит с того, что шаблонизатор jinja уже умеет автоматически экранировать все запрещенные символы, попадающие на страницу, тем самым защищая пользователя от XSS- уязвимости.

Отключить санитизацию символов можно при помощи блока

{$ autoescape false %}

Данный блок отключает автоматическое экранирование целых частей шаблона, что крайне не рекомендуется и может привести к XSS уязвимости. Но все же в jinja есть несколько кейсов, которые шаблонизатор не может обработать, приводя к уязвимости.

Атрибут без кавычек

HTML способен обработать атрибут, записанный без ковычек

<div class=block></biv>

Подобная конструкция при использовании шаблонизатора является потенциальным векторм XSS, так как злоумышленник может внедрить обработчики JavaScript, которым не требуются символы HTML.

<div class={{user-input}}>

В данном случае пользователь способен внедрить следующий payload class onclick=alert() и в результате получится

<div class="class" onclick=alert()>

При формировании DOM структуры сайта, кавычки атрибута class автоматически закроются, но внедренный атрибут останется на странице.

Решение

Если ограничить атрибут кавычками, тогда приведенный выше payload не сработает, а выйти из кавычек, посредством добавления следующего пейлоада не получится.

class" onclick"alert()

jinja отфильтрует входную кавычку, тем самым не допустив инъекции.

Атрибут href

Переменные шаблона в атрибуте href способны принимать схему javascript:, что так же приводит к XSS уязвимости

<a href"{{user-input}}"> click me </a>
<a href="javascript:alert()"> click me </a>

Решение

Предотвратить это позволяет использование url_for() для безопасного создания URL. Такая конструкция в Flask используется для создания URL-адреса, чтобы предотвратить изменение URL-адресов в приложении (в том числе в шаблонах).

@app.route('/index')
@app.route('/')
def index():
    return 'you are in the index page'

Теперь мы имеем ссылку на индексную страницу и в шаблоне можем использовать это

<a href={{ url_for('index') }}>Index</a>