-1

Previous question on this issue is here. CSRF token continues to fail on Flask-WTF forms. Config and details of setup are in the link.

What I've now discovered is that on my template, to which I pass two forms in the view, the csrf_token on each form isn't unique. I don't quite understand why? The CSRF tokens should be unique per form right?

I checked the tokens in Chrome, and they're identical - both included in the bottom block of code.

 <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">

phil0s0pher
  • 231
  • 1
  • 4
  • 16

1 Answers1

0

That's bacause token is cached for the whole request. See the comment for token generation function https://github.com/lepture/flask-wtf/blob/master/flask_wtf/csrf.py#L20

Another interesting issue is that you get 2 HTML elements in the same document with the same id attribute.

zgoda
  • 12,775
  • 4
  • 37
  • 46
  • Yes I spotted that - I don't know whats causing that, but it's surely not right. My setup is in previous link. – phil0s0pher Jan 16 '20 at 11:47
  • This is caused by default that's used in https://flask-wtf.readthedocs.io/en/stable/api.html#flask_wtf.csrf.generate_csrf. If you render multiple forms on a page all of them will have the same id for csrf token field because there is only one token in session. I'd say this is a bug so don't put 2 forms on one page or your javascripts may behave strange. – zgoda Jan 16 '20 at 13:19
  • Would this cause the verification to fail? I was sure I had this working.... If I have two forms sent to the same page, how can I handle the CSRF token behaviour? – phil0s0pher Jan 16 '20 at 13:29
  • No, each form is submitted nad processed separately so it won't affect form validation. It will break HTML DOM, you will see this in javascript (CSS is hardly applied to hidden inputs). – zgoda Jan 16 '20 at 13:39
  • The validation is failing still, no matter how I cook it. – phil0s0pher Jan 16 '20 at 13:59