flask-wtf icon indicating copy to clipboard operation
flask-wtf copied to clipboard

Exposure of the `csrf_token` field value

Open fdanielsen opened this issue 8 years ago • 5 comments

Previously Flask-WTF stripped away the csrf_token field value when accessing the form data. But in 42befd0420d1f4896a70339de3d474044461a1c9 this was removed.

Is this intentional? Now a form will expose the token as part of the data, even though it's an implicit value not generally useful outside the form.

I realize it is WTForms that implements the general logic for supporting CSRF validation, so maybe this is viewed as the responsibility of WTForms in the same way that form.populate_obj explicitly avoids populating the CSRF field value on the object. Sadly WTForms has no such filtering when accessing form.data, and the filtering in Flask-WTF was useful as it was.

I'll raise an issue with WTForms if that's where you think this should be fixed.

fdanielsen avatar Jun 16 '17 07:06 fdanielsen

Is there any update on this issue? We are currently forced to pinning Flask-WTF to 0.13.1, while considering simliar issues/solutions described by @fdanielsen.

slint avatar Jul 25 '17 12:07 slint

@slint We're still "manually" filtering out the CSRF token as needed. We would be happy to try and provide a pull request once time allows, but we've been waiting on feedback on whether or not this should be fixed in Flask-WTForms or WTForms.

fdanielsen avatar Jul 25 '17 13:07 fdanielsen

@fdanielsen You can leave a helper function here right now. In case anyone seeks the same problem.

lepture avatar Oct 24 '17 22:10 lepture

I've run into a tangentially related issue recently while updating old dependencies (including an old version of flask-wtf). For us, it broke forms dynamically generated and used by Flask-SuperAdmin.

Here's what fixed it for us:

from flask_superadmin import model
from flask_superadmin.model.backends.mongoengine.orm import data_to_document


class OurAdmin(model.ModelAdmin):
    @classmethod
    def _patch_form_populate_obj(cls, form):
        # wtforms started returning csrf token as a part of the data as well,
        # which we don't want to use when populating models
        def new_populate_obj(form, obj):
            data = {k: v for k, v in form.data.items() if k != 'csrf_token'}
            data_to_document(obj, data)
            return obj

        form.populate_obj = new_populate_obj
        return form

    def get_form(self):
        return self._patch_form_populate_obj(super().get_form())

Sorry, I know this isn't terribly relevant to flask-wtf, but hopefully it'll help someone else who has the same problem and finds this github issue.

AlecRosenbaum avatar Oct 28 '20 19:10 AlecRosenbaum

@lepture Sorry for not getting back with an example fix for others. Reminded by @AlecRosenbaum's recent post, I'll share our FlaskForm specific solution which is just a simple wrapper around the data property in a subclass:

class BaseFlaskForm(FlaskForm):
    @property
    def data(self):
        return dict(
            (name, f.data) for name, f in self._fields.items() if name != "csrf_token"
        )

fdanielsen avatar Oct 30 '20 08:10 fdanielsen