CSRF protection on AJAX authentication in Flask

2024/10/5 20:16:24

I'd like to AJAXify both a login and a signup form on a site. Up to now I've been using WTForms mainly for its built-in CSRF protetion, but for this project I didn't feel like it was worth it -- an extra layer of abstraction, and therefore frustration, for something that should be pretty simple.

So I came across this snippet on Flask's security section:

@app.before_request
def csrf_protect():if request.method == "POST":token = session.pop('_csrf_token', None)if not token or token != request.form.get('_csrf_token'):abort(403)def generate_csrf_token():if '_csrf_token' not in session:session['_csrf_token'] = some_random_string()return session['_csrf_token']app.jinja_env.globals['csrf_token'] = generate_csrf_token

I understand the thought process behind this code. In fact, it all makes perfect sense to me (I think). I can't see anything wrong with it.

But it doesn't work. The only thing I've changed about the code is replacing the pseudofunction some_random_string() with a call to os.urandom(24). Every request has 403'd so far because token and request.form.get('_csrf_token') are never the same. When I print them this becomes obvious -- usually they're different strings, but occasionally, and seemingly with no underlying reason, one or the other will be None or a truncated version of the output of os.urandom(24). Obviously something out of sync, but I'm not understanding what it is.

Answer

You can get the convenience of flask-wtf without all the heaviness, and without rolling your own:

from flask_wtf.csrf import CsrfProtect

then on init, either:

CsrfProtect(app)

or:

csrf = CsrfProtect()def create_app():app = Flask(__name__)csrf.init_app(app)

The token will then be available app-wide at any point, including via jinja2:

<form method="post" action="/"><input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</form>

(via the docs)

https://en.xdnf.cn/q/73342.html

Related Q&A

Pandas groupby and Multiindex

Is there any opportunity in pandas to groupby data by MultiIndex? By this i mean passing to groupby function not only keys but keys and values to predefine dataframe columns?a = np.array([foo, foo,…

How to dump YAML with explicit references?

Recursive references work great in ruamel.yaml or pyyaml: $ ruamel.yaml.dump(ruamel.yaml.load(&A [ *A ])) &id001 - *id001However it (obviously) does not work on normal references: $ ruamel.yaml…

How to set a Pydantic field value depending on other fields

from pydantic import BaseModelclass Grafana(BaseModel):user: strpassword: strhost: strport: strapi_key: str | None = NoneGRAFANA_URL = f"http://{user}:{password}@{host}:{port}"API_DATASOURCES…

Cascade multiple RNN models for N-dimensional output

Im having some difficulty with chaining together two models in an unusual way. I am trying to replicate the following flowchart:For clarity, at each timestep of Model[0] I am attempting to generate an …

Pandas Flatten a list of list within a column?

I am trying to flatten a column which is a list of lists:var var2 0 9122532.0 [[458182615.0], [79834910.0]] 1 79834910.0 [[458182615.0], [9122532.0]] 2 458182615.0 [[79834910.0], [9122…

How to use libxml2 with python on macOs?

Im on OSX Lion and I have libxml2 installed (by default) and I have python installed (by default) but they dont talk to one another. Whats the simplest way to make this work on Lion?$ python -c "…

SMTP Authentication error while while sending mail from outlook using python language

import smtplibsmtpObj = smtplib.SMTP(smtp.office365.com, 587)smtpObj.ehlo()smtpObj.starttls()smtpObj.login([email protected], abcde)smtpObj.sendmail([email protected], [email protected], Subject: So l…

How do you change environment of Python Interactive on Vscode?

I recently migrated from Spyder to VScode. I created a new conda environment and used setting.json to change the environment in VScode, "python.pythonPath": "/Users/dcai/anaconda3/envs/…

Validate list in marshmallow

currently I am using marshmallow schema to validate the request, and I have this a list and I need to validate the content of it.class PostValidationSchema(Schema):checks = fields.List(fields.String(re…

Save unicode in redis but fetch error

Im using mongodb and redis, redis is my cache.Im caching mongodb objects with redis-py:obj in mongodb: {uname: umatch, usection_title: u\u6d3b\u52a8, utitle: u\u6bd4\u8d5b, usection_id: 1, u_id: Objec…