PYTHON

Secure Flask Apps with CSRF Protection using Flask-CSRFProtect

Protect your Python Flask web application from Cross-Site Request Forgery (CSRF) attacks by integrating the Flask-CSRFProtect extension to manage CSRF tokens.

from flask import Flask, render_template_string, request, redirect, url_for, flash
from flask_wtf.csrf import CSRFProtect

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

# Initialize CSRF protection
csrf = CSRFProtect(app)

# Basic form template for demonstration
FORM_TEMPLATE = """
    <!doctype html>
    <title>CSRF Demo</title>
    <h1>Update Profile</h1>
    {% with messages = get_flashed_messages() %}
      {% if messages %}
        <ul class=flashes>
        {% for message in messages %}
          <li>{{ message }}</li>
        {% endfor %}
        </ul>
      {% endif %}
    {% endwith %}
    <form method="post" action="{{ url_for('update_profile') }}">
        {{ csrf_token() }}
        <label for="username">New Username:</label>
        <input type="text" id="username" name="username" value="{{ username }}"><br><br>
        <input type="submit" value="Update">
    </form>
"""

@app.route('/', methods=['GET'])
def index():
    return render_template_string(FORM_TEMPLATE, username="current_user")

@app.route('/update_profile', methods=['POST'])
# @csrf.exempt # IMPORTANT: Remove this line to enable CSRF protection for this route
def update_profile():
    # In a real app, you would retrieve and validate form data here
    new_username = request.form.get('username')
    flash(f'Profile updated for: {new_username}')
    print(f"User profile updated to: {new_username}")
    return redirect(url_for('index'))

if __name__ == '__main__':
    app.run(debug=True)

# To test CSRF protection:
# 1. Run the app.
# 2. Go to http://127.0.0.1:5000/
# 3. View source and copy the form HTML (including the hidden CSRF token input).
# 4. Remove the <input type="hidden" name="csrf_token" ... > line.
# 5. Save this modified HTML as a new file (e.g., evil.html).
# 6. Change the 'action' attribute in evil.html to point to your running app: action="http://127.0.0.1:5000/update_profile"
# 7. Open evil.html in your browser and submit the form.
#    - With @csrf.exempt: The update will succeed (vulnerable).
#    - Without @csrf.exempt: The update will fail with a CSRF error (protected).
How it works: This Python Flask snippet demonstrates how to implement robust Cross-Site Request Forgery (CSRF) protection using the Flask-CSRFProtect extension. By integrating `CSRFProtect`, the application automatically generates and validates unique CSRF tokens for POST requests, ensuring that sensitive actions can only be performed by legitimate requests originating from the application's own forms, thereby preventing attackers from tricking users into executing unintended actions.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs