Skip to content

stackxp/flask-csrf

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 

Repository files navigation

Flask CSRF

A lightweight CSRF protection script for Flask.

How to use

In your Python script:

import flask
# Import the script
import csrf

app = flask.Flask(__file__)

# Create a CSRFManager and bind it to the Flask app
csrf_manager = csrf.CSRFManager()
csrf_manager.init_app(app)

And in your templates:

<form>
	<input type="text" name="username">
	<input type="password" name="password">
	<!-- Include the csrf_token tag in the forms -->
	{{ csrf_token() }}
	<input type="submit" name="Log in">
</form>

And that's it! 🥳

By default, all post requests are secured, but by setting the protect_unsafe flag to False when creating the CSRFManager. Now, you have to decorate each post request you want to protect:

@app.post("/new")
@csrf_manager.csrf_protect()
def new():
	...

What is CSRF?

CSRF or Cross-Site Request Forgery is when an attacker tricks users into interacting with a website in unintended ways.

For example, let's say that there is a bank, whose website isn't CSRF protected. Users can send and receive money using simple HTML forms, which are sent to an endpoint on the server using a POST request. A malicious actor can now try to embed a form in some other site that sends a request to your server, for example:

<!-- The attacker's site -->

<h1>Sign up to the newsletter!</h1>
<!-- Fake input elements -->
<input type="email" placeholder="Your email">
<input type="text" placeholder="Your name">

<!-- And the submit button, with a form pointing the bank! -->
<form method="post" action="https://bigbank.com/money/send">
	<!-- And a hidden input element with a payload -->
	<input type="hidden" name="recipient" value="evil_hacker@gmail.com">
	<input type="hidden" name="anmount" value="$100000">
	<input type="submit" value="Subscribe">
</form>

So now, when people try to sign up for the newsletterm they instead accidentally send a 100 thousand dollars to the hacker.

This can be circumvented embedding a special token in the forms and validating them on the server. So now:

<!-- On the bank's website -->
<form method="post" action="/money/send">
	<input type="email" name="recipient">
	<input type="number" name="anmount">
	<!-- The CSRF token -->
	<input type="hidden" name="csrf_token" value="ru839fduwef832meiocewh">
	<input type="submit" value="Send">
</form>

This token gets generated and inserted on the server every time a form element is being sent. And when the form is submitted, the server checks for the token and rejects the request when it is not there, so when people try to make those fake forms, they can't because they don't have the token.

Of course, banks these days use a far more secure system than just raw HTML forms.

For more information, visit Hacksplaining.

About

A lightweight CSRF protection script for Flask

Topics

Resources

Stars

Watchers

Forks

Languages