0
0
FlaskHow-ToBeginner · 4 min read

How to Use CSRF Protection in Flask: Simple Guide

To use CSRF protection in Flask, install and configure the Flask-WTF extension which adds a secure token to your forms automatically. Enable it by setting a SECRET_KEY in your app and using FlaskForm for your forms to include CSRF tokens that protect against cross-site request forgery attacks.
📐

Syntax

To enable CSRF protection in Flask, you need to:

  • Set a SECRET_KEY in your Flask app for security.
  • Use the Flask-WTF extension which provides CSRFProtect and FlaskForm.
  • Create forms by inheriting from FlaskForm which automatically adds a hidden CSRF token field.
  • Use csrf.init_app(app) to activate CSRF protection on your app.
python
from flask import Flask
from flask_wtf import FlaskForm, CSRFProtect
from wtforms import StringField, SubmitField

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'

csrf = CSRFProtect()
csrf.init_app(app)

class MyForm(FlaskForm):
    name = StringField('Name')
    submit = SubmitField('Submit')
💻

Example

This example shows a simple Flask app with CSRF protection enabled using Flask-WTF. The form includes a CSRF token automatically, and submitting the form validates the token to prevent CSRF attacks.

python
from flask import Flask, render_template_string, request
from flask_wtf import FlaskForm, CSRFProtect
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired

app = Flask(__name__)
app.config['SECRET_KEY'] = 'a-very-secret-key'

csrf = CSRFProtect()
csrf.init_app(app)

class NameForm(FlaskForm):
    name = StringField('Your Name', validators=[DataRequired()])
    submit = SubmitField('Submit')

@app.route('/', methods=['GET', 'POST'])
def index():
    form = NameForm()
    if form.validate_on_submit():
        return f"Hello, {form.name.data}!"
    return render_template_string('''
        <form method="POST">
            {{ form.hidden_tag() }}
            {{ form.name.label }} {{ form.name() }}<br>
            {{ form.submit() }}
        </form>
    ''', form=form)

if __name__ == '__main__':
    app.run(debug=True)
Output
Running the app and visiting '/' shows a form with a name input and submit button. Submitting the form with a name displays a greeting like "Hello, Alice!". If the CSRF token is missing or invalid, the form submission is rejected with a 400 error.
⚠️

Common Pitfalls

  • Not setting SECRET_KEY causes CSRF protection to fail silently or raise errors.
  • Forgetting to use FlaskForm or form.hidden_tag() in templates means the CSRF token is not included.
  • Disabling CSRF protection on POST routes by mistake leaves your app vulnerable.
  • Using AJAX or API calls without sending the CSRF token causes validation failures.
python
from flask import Flask, render_template_string
from flask_wtf import FlaskForm, CSRFProtect
from wtforms import SubmitField

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'

csrf = CSRFProtect()
csrf.init_app(app)

class BadForm(FlaskForm):
    submit = SubmitField('Submit')

@app.route('/', methods=['GET', 'POST'])
def bad():
    form = BadForm()
    if form.validate_on_submit():
        return 'Success'
    return render_template_string('''
        <form method="POST">
            <!-- Missing form.hidden_tag() -->
            {{ form.submit() }}
        </form>
    ''', form=form)

# Correct way includes form.hidden_tag() to add CSRF token

@app.route('/good', methods=['GET', 'POST'])
def good():
    form = BadForm()
    if form.validate_on_submit():
        return 'Success'
    return render_template_string('''
        <form method="POST">
            {{ form.hidden_tag() }}
            {{ form.submit() }}
        </form>
    ''', form=form)
📊

Quick Reference

  • Always set app.config['SECRET_KEY'] before enabling CSRF.
  • Use FlaskForm for your forms to get CSRF tokens automatically.
  • Include {{ form.hidden_tag() }} in your form templates to insert the CSRF token field.
  • Enable CSRF protection with CSRFProtect(app).
  • For AJAX requests, send the CSRF token in headers or data.

Key Takeaways

Set a strong SECRET_KEY in your Flask app to enable CSRF protection.
Use Flask-WTF's FlaskForm to automatically add CSRF tokens to your forms.
Always include form.hidden_tag() in your HTML forms to insert the CSRF token field.
Enable CSRFProtect on your app to activate CSRF validation on POST requests.
Remember to send CSRF tokens with AJAX requests to avoid validation errors.