RSTR-CSRF-001 — Flask WTF_CSRF_ENABLED disabled

Summary

Flask-WTF's CSRF protection is disabled globally (WTF_CSRF_ENABLED = False or app.config['WTF_CSRF_ENABLED'] = False). Every state-changing form in the app is now vulnerable to cross-site request forgery: an attacker who gets the victim to visit a page they control can submit a form to your app using the victim's cookies.

Severity

High.

Languages

Python.

How to fix it

Leave the default in place — WTF_CSRF_ENABLED defaults to True for a reason. Use {{ csrf_token() }} in every form:

<form method="POST" action="/profile">
  {{ csrf_token() }}
  <input name="name" />
  <button type="submit">Save</button>
</form>

For AJAX, set the X-CSRFToken header from {{ csrf_token() }} injected into a <meta> tag.

If a specific webhook handler legitimately can't have CSRF protection (e.g. Stripe webhook), exempt that one route:

@csrf.exempt
@app.route('/webhook/stripe', methods=['POST'])
def stripe_webhook():
    # verify Stripe signature instead
    ...

…not the whole app.

References