HTML中ajax表单提交CSRF保护

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HTML中ajax表单提交CSRF保护相关的知识,希望对你有一定的参考价值。

参考技术A 除了检查被作为 POST 参数传递的 CSRF token 之外, VerifyCsrfToken 中间件也会检查请求标头中的 X-CSRF-TOKEN 。例如,你可以将其保存在 meta 标签中:

一旦你创建了 meta 标签,你就可以使用 jQuery 之类的函数库将 token 自动地添加到所有的请求头中。这简单、方便的为你的应用的 AJAX 提供了 CSRF 保护:

如何通过 AJAX 使用 Flask-WTForms CSRF 保护?

【中文标题】如何通过 AJAX 使用 Flask-WTForms CSRF 保护?【英文标题】:How to use Flask-WTForms CSRF protection with AJAX? 【发布时间】:2015-10-31 12:33:39 【问题描述】:

Flask-WTForms 提供 CSRF 保护。它在使用普通 HTML 表单时效果很好,但在使用 AJAX 时过程不太清楚。我的表单中有一个文件上传,我使用 AJAX 将过程分成两部分:文件发送到 upload 端点,而表单的其余部分发送到 submit 端点。由于该文件是使用 AJAX 发布的,因此它没有获得 CSRF 令牌,但我想保护 upload 端点免受攻击。使用 AJAX 时如何生成 CSRF 令牌?

@app.route('/submit', methods=["GET","POST"])
@login_required
def submit():
    form = MyForm()

    if request.method == "POST" and form.validate():
        # success, csrf checks out and data is validated
        # do stuff

    csrf_for_uploads = # generate csrf?
    return render_template('some_form.html', form=form, csrf_for_uploads=csrf_for_uploads)

@app.route('/upload', methods=["POST"])
@login_required
def upload():
    myfile = request.files['file']
    # How do I verify CSRF now?

【问题讨论】:

【参考方案1】:

我在想 !/^ 是一个否定断言,所以如果请求不匹配 Get/Head 等且不跨域,则使用 csrf 令牌的值设置请求标头

【讨论】:

【参考方案2】:

documentation 谈到了关于 AJAX 实现 CSRF 保护的一些内容。

您可以启用该模块:

from flask_wtf.csrf import CsrfProtect

CsrfProtect(app)

然后在您的 AJAX POST 调用中使用它:

<meta name="csrf-token" content=" csrf_token() ">

var csrftoken = $('meta[name=csrf-token]').attr('content')

$.ajaxSetup(
    beforeSend: function(xhr, settings) 
        if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) 
            xhr.setRequestHeader("X-CSRFToken", csrftoken)
        
    
)

希望这会有所帮助!

【讨论】:

嗯,我完全错过了那个文档。是的,总结得差不多了。 您好,请注意:“FlaskWTFDeprecationWarning:“flask_wtf.CsrfProtect”已重命名为“CSRFProtect”,将在 1.0 中删除。” 有人可以解释一下“if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain)”是什么意思吗?谢谢! 此解决方案依赖于使用 jinja 渲染模板。有没有办法做到这一点?比如在响应中传递令牌? 如何使用 fetch API 做到这一点?

以上是关于HTML中ajax表单提交CSRF保护的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 4 CSRF 表单通过 Ajax 调用提交

Ajax GET 请求后表单提交失败(无效的 CSRF 令牌)。怎么修?

更改提交时 Ajax 表单上的 CSRF 令牌不匹配

表单 AJAX 提交执行 CSRF 安全过滤

Spring Security CSRF 令牌不适用于 AJAX 调用和表单提交在同一个 JSP 中

Laravel csrf 令牌在 ajax 上第二次不匹配