【问题标题】:CSRF token on two unique 'FlaskForm' objects are not unique, CSRF fails [duplicate]两个唯一的“FlaskForm”对象上的 CSRF 令牌不是唯一的,CSRF 失败 [重复]
【发布时间】:2020-05-03 03:42:58
【问题描述】:

关于这个问题的上一个问题是here。 CSRF 令牌在 Flask-WTF 表单上继续失败。配置和设置的详细信息在链接中。

我现在发现在我的模板上,我在视图中传递了两个表单,每个表单上的 csrf_token 不是唯一的。我不太明白为什么? CSRF 令牌应该是唯一的 per 形式对吗?

我在 Chrome 中检查了令牌,它们是相同的 - 都包含在底部代码块中。

 <form method="post" class="mt-4" id="form_1">
                            {{ form1.csrf_token }}
                            <div class="form-group"
                                {{ form1.form_field1(class_='form-control', id='foo', type='text',
                                placeholder='Enter your data') }}
                            </div>
                            <div class="form-group">
                                {{ form1.form_field2(class_='form-control', id='bar',
                                type='text', placeholder='More data please') }}
                            </div>
                              {{ form1.submit(class_='btn btn-lg btn-info btn-block', form='form_1' ) }}
<!--                            <button form="form_1" type="submit"-->
<!--                                    class="btn btn-lg btn-info btn-block">-->
<!--                                <i class="fa fa-lock fa-lg"></i>&nbsp;-->
<!--                            </button>-->
                        </form>



<form class="mt-3" method="post" id="form_2">
                            <div class="form-group input-group">

                                {{ form2.csrf_token }}
                                {% if current_user.has_value() %}
                                {{form2.field(type='checkbox', checked=1)}}
                                {% else %}
                                {{ form2.field(type='checkbox') }}
                                {% endif %}
                                {{ form2.update(type='submit', class_='btn btn-light input-group-append') }}
                            </div>
                        </form>

<form method="post" class="mt-4" id="form_1">
<input id="csrf_token" name="csrf_token" type="hidden" value="ImM5OWI2NTJiY2RhOGJkNjlkYjFkYzliM2JkMDM4N2JmODQwMDU1YWQi.XiAz0A.7r1lBMq-tO0wrukerCfIFgXwK9M">

.....

 <form class="mt-3" method="post" id="form_2">
 <div class="form-group input-group">
 <input id="csrf_token" name="csrf_token" type="hidden" value="ImM5OWI2NTJiY2RhOGJkNjlkYjFkYzliM2JkMDM4N2JmODQwMDU1YWQi.XiAz0A.7r1lBMq-tO0wrukerCfIFgXwK9M">

【问题讨论】:

    标签: flask jinja2 csrf flask-wtforms


    【解决方案1】:

    这是因为令牌被缓存用于整个请求。令牌生成功能见评论https://github.com/lepture/flask-wtf/blob/master/flask_wtf/csrf.py#L20

    另一个有趣的问题是,您在同一个文档中获得了具有相同 id 属性的 2 个 HTML 元素。

    【讨论】:

    • 是的,我发现了——我不知道是什么原因造成的,但这肯定是不对的。我的设置在上一个链接中。
    • 这是由flask-wtf.readthedocs.io/en/stable/… 中使用的默认值引起的。如果您在一个页面上呈现多个表单,所有这些表单都将具有相同的 csrf 令牌字段 id,因为会话中只有一个令牌。我会说这是一个错误,所以不要在一个页面上放置 2 个表单,否则你的 javascripts 可能会表现得很奇怪。
    • 这会导致验证失败吗?我确信我有这个工作......如果我有两个表单发送到同一个页面,我该如何处理 CSRF 令牌行为?
    • 不,每个表单都是单独提交和处理的,因此不会影响表单验证。它会破坏 HTML DOM,你会在 javascript 中看到这一点(CSS 几乎不会应用于隐藏的输入)。
    • 验证仍然失败,不管我怎么做。
    猜你喜欢
    • 1970-01-01
    • 2014-10-19
    • 2014-12-25
    • 2014-02-26
    • 2021-10-01
    • 2014-03-31
    • 2016-06-19
    • 2013-07-30
    • 2021-11-23
    相关资源
    最近更新 更多