Commit db21a600 authored by Andrew Grigorev's avatar Andrew Grigorev

Fix CSRF for production deployments

Current SecureForm implementation generates CSRF secret using
`os.urandom()` every time when application start up. CSRF secret is used
to calculate csrf_token check value, so if someone would use a command
similar to

    gunicorn --workers=8 app

to run his flask-admin app on production then most form submissions
would silently fail (silently - as for now, it is probably another one
bug).

Instead of custom `os.urandom()` logic the `app.secret_key` value should
be used to produce CSRF token values.
parent d7ee730a
......@@ -43,8 +43,9 @@ def recreate_field(unbound):
if int(wtforms_version[0]) > 1:
# only WTForms 2+ has built-in CSRF functionality
from os import urandom
from flask import session
from flask import session, current_app
from wtforms.csrf.session import SessionCSRF
from flask_admin._compat import text_type
class SecureForm(BaseForm):
"""
......@@ -55,7 +56,14 @@ if int(wtforms_version[0]) > 1:
class Meta:
csrf = True
csrf_class = SessionCSRF
csrf_secret = urandom(24)
_csrf_secret = urandom(24)
@property
def csrf_secret(self):
secret = current_app.secret_key or self._csrf_secret
if isinstance(secret, text_type):
secret = secret.encode('utf-8')
return secret
@property
def csrf_context(self):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment