Formulaire de validation échoue en raison manquant CSRF
Il y A quelques jours j'ai réinitialiser mon local flacon de l'environnement sans avoir capturé les dépendances via un pip freeze
avant je l'ai supprimé. Par conséquent, j'ai dû ré-installer la version la plus récente de l'ensemble de la pile.
Maintenant hors de la bleue, je ne suis plus en mesure de valider avec les formes. Flacon revendications CSRF serait absente.
def register():
form = RegisterForm()
if form.validate_on_submit():
...
return make_response("register.html", form=form, error=form.errors)
La première fois que j'envoie un Get
- je récupérer un vide form.errors
comme prévu.
Maintenant je remplir le formulaire et de le soumettre et de form.errors
montre: {'csrf_token': [u'CSRF token missing']}
C'est tellement étrange. Je me demande si en Flacon de WTF a changé et je l'utilise à tort.
Je peux clairement voir la form.CSRF_token
existe, alors pourquoi est-il en affirmant qu'il manquait?
CSRFTokenField: <input id="csrf_token" name="csrf_token" type="hidden" value="1391278044.35##3f90ec8062a9e91707e70c2edb919f7e8236ddb5">
Je n'ai jamais touché le travail de modèle, mais je l'ai poster ici néanmoins:
{% 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 %}
Est-ce un nouveau bug?
Mise à JOUR:
J'ai réinstallé le tout et le problème persiste.
Que Martijn a suggéré, je suis de débogage dans la méthode suivante dans 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'))
La dernière condition est la collecte de l'erreur de validation.
field.data = "1391296243.8##1b02e325eb0cd0c15436d0384f981f06c06147ec"
self.SECRET_KEY = None (? Is this the problem)
self.TIME_LIMIT = 3600
Et vous avez eu raison de la HMAC échec de la comparaison....les deux valeurs sont à chaque fois différents.
return hmac_compare == hmac_csrf
J'ai à la fois SECRET_KEY et CSRF_SESSION_KEY dans ma config défini.
csrf_token
valeur est présente dans la session et valide; c'est une valeur aléatoire utilisé pour signer le jeton et le poster est utilisé pour vérifier le jeton CSRF avec le formulaire (avec le serveur-côté secret).Oui, Ni Firefox ni Chrome sont le blocage des cookies. Je ne comprends pas.
Donc, pour vérifier, vous voyez l'un cookie nommé
session
set (à condition de ne pas en SESSION_COOKIE_NAME
à autre chose)?Oui. Dans Eclipse, en vertu de Débogage de la liste de surveillance, quand je rentre
session
, j'obtiens ceci: LocalProxy: <SecureCookieSession {'csrf_token': '2182effc89ce180a53622272d88d4466679920cd'}>
J'ai eu ce problème pendant une longue période, réalisé que c'était mon
SESSION_COOKIE_SECURE = True
paramètre d'application. Espérons que cela aide quelqu'un d'autre.OriginalL'auteur Houman | 2014-02-01
Vous devez vous connecter pour publier un commentaire.
Le Flacon WTF CSRF infrastructure rejette un jeton si:
le jeton est manquant. Pas le cas ici, vous pouvez voir le jeton dans la forme.
il est trop vieux (d'expiration par défaut est définie à 3600 secondes ou une heure). Définir la
TIME_LIMIT
attribut sur les formes de remplacer cette. Sans doute pas le cas ici.si aucune
'csrf_token'
clé se trouve dans la session en cours. Vous pouvez apparemment voir le jeton de session, de sorte que c'est trop.Si le HMAC signature ne correspond pas; la signature est basé sur l'aléatoire de la valeur définie dans la session en vertu de la
'csrf_token'
clé, du côté serveur, le secret, et la date et heure d'expiration dans le jeton.Ayant éliminé les trois premières possibilités, vous devez vérifier pourquoi la 4ème étape échoue. Vous pouvez déboguer la validation dans
flask_wtf/csrf.py
fichier, dans levalidate_csrf()
fonction.Pour votre installation, vous devez vérifier que la configuration de la session est correct (surtout si vous n'utilisez pas la valeur par défaut configuration de session), et que vous utilisez le bon côté serveur secret. Le formulaire lui-même pourrait avoir un
SECRET_KEY
ensemble d'attributs, mais n'est pas stable entre les requêtes, ou de l'applicationWTF_CSRF_SECRET_KEY
clé a changé (ce dernier est par défaut leapp.secret_key
valeur).Le CSRF de soutien a été ajouté dans la version 0.9.0, faire vérifier les Protection CSRF de la documentation si vous avez mis à niveau. La norme en Flacon de WTF
Form
classe comprend le jeton CSRF comme un champ caché, rendu les champs masqués est assez pour la comprendre:OriginalL'auteur Martijn Pieters
J'ai enfin trouvé le problème après presque une journée de travail. 🙁
Un grand merci à Martijn bien que pour son aide.
Le véritable problème réside dans la façon dont la dernière
flask_wtf.csrf
est de travail. Les décideurs ont remanié complètement.Vous devez remplacer tous les
{{form.hidden_tag()}}
dans vos modèles avec les<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
.Et vous devez maintenant activer la protection CSRF explicitement par l'ajout de
CsrfProtect(app)
.La la documentation manifestement, reflet, mais je ne sais pas ce qui a changé et a été la chasse aux fantômes.
Ses un gros problème avec la fonctionnalité obsolète sans en informer le développeur en quelque sorte. Toute personne qui met à niveau maintenant avec la dernière version, sera la chasse aux fantômes comme je l'ai fait. Mais il est aussi de ma faute de ne pas avoir pris un instantané de mes dépendances. Leçon apprise à la dure.
hidden_tag()
, mais leCsrfProtect(app)
est certainement nécessaire.Aussi,
self.SECRET_KEY
est le par-formulaire de secret, quand il est àNone
, le secret de l'app est utilisée.Grâce Martijn, j'ai trouvé une autre question. Je suis déploiement sur GAE. Il semble
flask_wtf
est en collision avecFlask-DebugToolbar
. Quand j'ai désactivertoolbar = DebugToolbarExtension(app)
, CSRF est de travailler sur l'environnement de développement. Mais uniquement les développeurs sont concernés que sont l'aideflask-appengine-template
. 🙂Intéressant. Mon projet actuel est à l'aide de ballon sur GAE, mais je n'ai pas utilisé les modèles, ni les utiliser en Flacon de DebugToolbar. Si je le fais, je vais regarder pour toute questions.
J'ai maintenant plusieurs projets à la fois avec la barre d'outils de débogage et les formulaires de protection CSRF. Si vous êtes seulement en utilisant FlaskForm formes, CSRFProtect n'est pas nécessaire tout et tout ce que vous devez dans un modèle de
form.hidden_tag()
de sortie. En d'autres termes, vous ne devez utiliser"{{ csrf_token() }}
et CSRFProtect pour les vues qui n'utilisent pas un FlaskForm objet de formulaire!OriginalL'auteur Houman
Pour moi, le problème ne venait pas de Flacon-WTF être mal configuré, ou la disparition d'un jeton. Il a été à venir dans les variables d'environnement.
Si votre ballon serveur n'est pas en cours d'exécution sur localhost puis dans l'ordre pour obtenir Flacon pour fonctionner correctement, vous devez définir un
SERVER_NAME
variable d'environnement. Vous avez probablement oublié de modifier leSERVER_NAME
valeur quelque part.Par exemple, vous pourriez avoir quelque chose comme ceci dans
config/settings.py
:Pour plus d'informations, consultez cette excellente ressource
OriginalL'auteur louis_guitton
Au moment de la création de l'app:
OriginalL'auteur caverac