[英]CSRF protection on AJAX authentication in Flask
我想同时使用AJAXify网站上的登录名和注册表。 到目前为止,我一直主要将WTForms用于其内置的CSRF保护,但是对于这个项目,我并不认为这是值得的-额外的抽象层,因此令人沮丧,因为它应该很漂亮简单。
因此,我在Flask的安全性部分遇到了以下片段 :
@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
我了解此代码背后的思考过程。 实际上,这对我来说完全有意义(我认为)。 我看不出有什么问题。
但这是行不通的。 我对代码所做的唯一更改是将伪函数some_random_string()
替换为对os.urandom(24)
的调用。 到目前为止,每个请求都有403,因为token
和request.form.get('_csrf_token')
永远都不相同。 当我打印它们时,这很明显-通常它们是不同的字符串,但偶尔,而且似乎没有根本原因,一个或另一个将是None
或os.urandom(24)
输出的截断版本。 显然有些东西不同步,但我不明白它是什么。
您可以在没有所有flask-wtf
情况下获得flask-wtf
的便利,也无需自己动手:
from flask_wtf.csrf import CsrfProtect
然后在init上:
CsrfProtect(app)
要么:
csrf = CsrfProtect()
def create_app():
app = Flask(__name__)
csrf.init_app(app)
该令牌随后将在整个应用范围内可用,包括通过jinja2
:
<form method="post" action="/">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</form>
(通过文档 )
我认为您的问题是os.urandom函数。 此函数的结果可能包含无法在html中正确解析的符号。 因此,当您在html中插入csrf_token并且不进行任何转义时,就会遇到上述问题。
怎么修。 尝试在html中转义csrf_token (请参阅文档),或使用其他方法生成csrf令牌。 例如使用uuid:
import uuid
...
def generate_random_string():
return str(uuid.uuid4())
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.