Flask-WTF CSRF
Если приложение использует библиотеку Flask-WTF, предоставляющую возможность работы с веб формами, то разработчик может допустить досадную ошибку, которая приведет к CSRF.
Первая ошибка, которую от разработчика требуется допустить - применить request.values для получения параметров запроса. request.values - это массив, в который кладутся все параметры запроса, независимо от того, какие это параметры - GET или POST.
Если взглянуть на
исходники Flask-WTF, можно увидеть список HTTP методов с которыми он работает. В списке нет GET. Это вполне логично и нормально.
Однако существует интересная особенность Flask в том, что он неявно обрабатывает запросы с HTTP методом HEAD, если конечная точка обрабатывает GET запросы. В целом, это правильно, ведь HEAD это тот же самый GET запрос -
HTTP RFC 2616.
Скомбинировав информацию из 3 предыдущих абзацев, можно идти искать вторую ошибку разработчика, а именно - отсутствие явной обработки POST запроса. Пример:
if request.method == "GET":
# do some GET flow
# do some POST flow
Теперь скомбинируем все вместе.
1. Конечные точки, обрабатывающие GET запросы также работают с HEAD запросами
2. CSRF токены не работают с GET запросами, а соотвественно и с HEAD.
3. Разработчик, не обрабатывая POST в отдельном if-блоке, дает возможность провести CSRF с методом HEAD.
PoC:
fetch('http://example/transfer?target_user_id=1&amount=1337', {method: 'HEAD'});
Притянутая за уши бага конечно, встретить которую второй раз будет очень большой удачей.
#web