2014-02-01 4 views
14

Несколько дней назад я сбросил локальную среду фляги, не зацепив зависимости через pip freeze, прежде чем удалю ее. Поэтому мне пришлось переустановить последнюю версию всего стека.Проверка формы не прошла должным образом CSRF

Теперь я не могу подтвердить форму с помощью формы. Флакон утверждает, что CSRF будет отсутствовать.

def register(): 
    form = RegisterForm() 
    if form.validate_on_submit(): 
     ... 
    return make_response("register.html", form=form, error=form.errors) 

Первый раз, когда я отправить Get я получить пустой form.errors, как и ожидалось. Теперь я заполняю форму и отправлю ее, и form.errors показывает: {'csrf_token': [u'CSRF token missing']}

Это так странно. Интересно, изменилась ли Flask-WTF, и я использую ее неправильно.

Я могу видеть, что form.CSRF_token существует, так почему он утверждает, что он отсутствовал?

CSRFTokenField: <input id="csrf_token" name="csrf_token" type="hidden" value="1391278044.35##3f90ec8062a9e91707e70c2edb919f7e8236ddb5"> 

Я никогда не касался рабочего шаблона, но я его здесь, тем не менее:

{% from "_formhelpers.html" import render_field %} 
{% extends "base.html" %} 
{% block body %} 
<div class="center simpleform"> 
    <h2>Register</h2> 
    {% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %} 
    <form class="form-signin" action="{{ url_for('register') }}" method=post> 
     {{form.hidden_tag()}} 
     <dl> 
      {{ render_field(form.name) }} 
      {{ render_field(form.email) }} 
      {{ render_field(form.password) }} 
      {{ render_field(form.confirm) }} 
      <dd><input type=submit value=Register class='btn btn-primary'> 
     </dl> 
    </form> 
</div> 
{% endblock %} 

Это новая ошибка?

UPDATE:

Я переустановил все, и проблема остается.

Как предложил Мартейн, я отладки в следующий метод в flask_wtf:

def validate_csrf_token(self, field): 
     if not self.csrf_enabled: 
      return True 
     if hasattr(request, 'csrf_valid') and request.csrf_valid: 
      # this is validated by CsrfProtect 
      return True 
     if not validate_csrf(field.data, self.SECRET_KEY, self.TIME_LIMIT): 
      raise ValidationError(field.gettext('CSRF token missing')) 

Последнее условие повышения ошибка проверки.

field.data = "1391296243.8##1b02e325eb0cd0c15436d0384f981f06c06147ec" 
self.SECRET_KEY = None (? Is this the problem) 
self.TIME_LIMIT = 3600 

И вы были правы, сравнение HMAC не удается .... оба значения в каждом разном отличаются друг от друга.

return hmac_compare == hmac_csrf 

У меня есть как SECRET_KEY, так и CSRF_SESSION_KEY в моей конфигурации.

+0

Вы принимаете печенье? Для архитектуры CSRF требуется, чтобы значение 'csrf_token' присутствовало в сеансе и было действительным; это случайное значение, используемое для подписи токена, и при публикации он используется для проверки токена CSRF с формой (вместе с секретностью на стороне сервера). –

+0

Да, ни Firefox, ни Chrome не блокируют файлы cookie. Я не понимаю. – Houman

+0

Итак, чтобы убедиться, что вы видите файл cookie с именем 'session' (если вы не задали' SESSION_COOKIE_NAME' что-то еще)? –

ответ

14

Колбу-WTF CSRF инфраструктура отклоняет токен, если:

  • маркер отсутствует. Не здесь, вы можете увидеть токен в форме.

  • Это слишком старый (значение по умолчанию установлено на 3600 секунд или час). Установите атрибут TIME_LIMIT на формы, чтобы переопределить это. Наверное, здесь не так.

  • если нет 'csrf_token' ключ находится в текущей сессии. Очевидно, вы видите токен сеанса, так что это тоже.

  • Если подпись HMAC не соответствует; подпись основана на случайном значении, установленном в сеансе под ключом 'csrf_token', секретной стороне сервера и меткой времени истечения в токене.

Исключив первые три возможности, вам необходимо проверить, почему 4-й шаг не удался. Вы можете отладить проверку в файле flask_wtf/csrf.py, в функции validate_csrf().

Для вашей установки вам необходимо убедиться, что настройка сеанса верна (особенно если вы не используете конфигурацию сеанса по умолчанию) и что вы используете правильную секретность на стороне сервера. Сама форма может иметь набор атрибутов SECRET_KEY, но не является стабильной в разных запросах, или изменилось ключ приложения WTF_CSRF_SECRET_KEY (последний по умолчанию равен app.secret_key value).

Поддержка CSRF была добавлена ​​в версии 0.9.0, проверьте, есть ли у вас CSRF protection documentation, если вы обновили. Стандарт Колба-WTF Form класс включает маркер CSRF, как скрытое поле, делая скрытые поля достаточно, чтобы включить его:

{{ form.hidden_tag() }} 
+0

Спасибо Martijn, ваша помощь очень ценится. Можете ли вы посмотреть мой обновленный вопрос? – Houman

+0

Отлично! Наконец, моя проверка формы работает. Постскриптум Исправление: '{{form.hidden_tag}}' NOT '{{form.hidden_tag()}}' – Hussain

+1

@nuin: я переключился на 'form.hidden_tag' (удаление вызова) после того, как кто-то утверждал, что он работал с этим синтаксис. Поскольку [текущий быстрый старт] (https://flask-wtf.readthedocs.org/en/latest/quickstart.html#creating-forms) явно вызывает метод, который, должно быть, был неправильным вызовом где-то. Спасибо за исправление! –

14

я, наконец, нашел проблему после того, как почти день работы на нем. :( Большое спасибо Martijn хотя за его помощь.

Реальная проблема заключается в том, как последняя flask_wtf.csrf работает. Создатели уже переработан полностью.

Вы должны заменить все {{form.hidden_tag()}} в шаблонах с <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>.

И вы должны теперь включить защиту CSRF явно добавляя CsrfProtect(app).

documentation теперь, очевидно, сообразив, что, но я не знаю, что это изменилось и преследовало призраков.

Его большая проблема с устаревшей функциональностью без уведомления разработчика как-то. Любой, кто обновляется до последней версии, будет преследовать призраков, как я. Но это также моя вина, не сделав снимок моих зависимостей. Урок усвоил трудный путь.

+2

Вам не нужно заменять 'hidden_tag()', но обязательно требуется 'CsrfProtect (приложение)'. –

+1

Кроме того, 'self.SECRET_KEY' является секретом каждой формы, когда для него установлено значение« Нет », используется секрет приложения. –

+0

Спасибо, Мартин, я нашел еще одну проблему. Я развертываю его на GAE. Кажется, что 'flask_wtf' сталкивается с' Flask-DebugToolbar'. Когда я отключу 'toolbar = DebugToolbarExtension (app)', CSRF работает над средой разработчика. Но затронуты только те разработчики, которые используют 'flask-appengine-template'. :) – Houman

Смежные вопросы