Csrf treatment principle and the flask
Why CSRF?
Flask-WTF Form protect you against CSRF threats, you do not need to have any concerns. Nevertheless, if you have a view that does not contain a form, they still need protection.
For example, POST transmitted from the AJAX request, but does not form behind it. In previous versions of Flask-WTF 0.9.0 you can not get CSRF token. This is why we want to achieve CSRF.
CSRF attack works:
A normal user login ① bank's website,
②A website returns cookie information to the user, the browser stores the cookie information
③ In the case of A site without logging in (or cookie information is not expired), logged a malicious Web site B
④ malicious Web site B, ready ahead of the transfer request form or another, to hide it. A button is set to submit to the site as a "receive coupons" image links. Users click on the link
⑤ in the user subjective unknown, A site visit, this time the browser will automatically carry the cookie information
⑥A site identification information to the cookie, the default is a request made by the user himself, and make the appropriate action according to request.
⑦ user receives a loss.
Specific steps:
The principle csrf_token verification, specific steps in the following steps:
1. the rear end of csrf_token generated value, when the front end interface request or register the values to the distal end, the distal end of the pass may have the following two ways:
in From template add a hidden form fields
will pass manner using a cookie csrf_token distal end
2. when the initiation request at the front end, or in the form csrf_token specified in the request header of the tape
3. after receiving the request at the rear end, to take csrf_token sent from the front end, with the value generated csrf_token first checking step
4. If the check of consistency csrf_token, represents a normal request, or a request may be counterfeit, not by
In the Flask, CSRFProtect this class specifically only csrf_token verification operation on the specified app, so developers need to do several things:
generating csrf_token value of
the value passed to the distal end of the browser csrf_token
band value at the front end of the request csrf_token
Then realized
Approach:
Backend writing:
In order to allow all views by CSRF protection function, need to open CsrfProtect modules:
from flask_wtf.csrf import CsrfProtect CsrfProtect(app)
Like any other extension, like Flask, you can load it inert:
from flask_wtf.csrf import CsrfProtect csrf = CsrfProtect() def create_app(): app = Flask(__name__) csrf.init_app(app)
Note
requires a secret key for the CSRF protection settings. Typically, SECRET_KEY with Flask application is the same.
Add protection operations in the form:
If there is a form template you do not need to do anything. As before:
<form method="post" action="/"> {{ form.csrf_token }} </form>
But if there is no template form, you need a CSRF token:
<form method="post" action="/"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" /> </form>
Custom error and close the corresponding protection:
Whenever not authenticated CSRF, 400 returns a response. You can customize this error response:
@csrf.error_handler def csrf_error(reason): return render_template('csrf_error.html', reason=reason), 400
Recommended to enable CSRF protection for all views. Also provides some view function does not require protection of decorators:
@csrf.exempt @app.route('/foo', methods=('GET', 'POST')) def my_handler(): # ... return 'ok'
It can also be disabled by default in all views CSRF protection, by setting WTF_CSRF_CHECK_DEFAULT to False, only when you need time to choose to call csrf.protect (). It is also able to do some pre-treatment before checking CSRF token:
@app.before_request def check_csrf(): if not is_oauth(request): csrf.protect()
Ajax submission of data:
Rendering CSRF token meta tag:
<meta name="csrf-token" content="{{ csrf_token() }}">
Rendering is also possible in the script tag:
<script type="text/javascript"> var csrftoken = "{{ csrf_token() }}" </script>
The following example uses meta tags in rendering mode, rendering the script will be easier, do not worry about no corresponding examples.
Whenever sending AJAX POST request, to add X-CSRFToken header:
var csrftoken = $(‘meta[name=csrf-token]').attr(‘content') KaTeX parse error: Expected '}', got 'EOF' at end of input: …|OPTIONS|TRACE)/i.test(settings.type) && !this.crossDomain) { xhr.setRequestHeader(“X-CSRFToken”, csrftoken) } } })
Or so write ajax:
when submitting a request, you need to add X-CSRFToken key-value pairs in the request header:
$.ajax({ ... headers: { "X-CSRFToken": getCookie("csrf_token") }, ... })
Troubleshooting
When defining the form, if this mistake: Import from wtforms the Form rather than importing from flask.ext.wtf, most CSRF protection function will work (except form.validate_on_submit ()), but the CSRF protection exception occurs. When the form is submitted, you will get Bad Request / CSRF token missing or incorrect error. This error occurs because import error, not a configuration problem.