Quick Jump: You Did Everything the Docs Stated|What Does Your Dev Environment Look Like?|What Causes Bad Request CSRF Token Missing?|Easily Fix the Problem for the Time Being|An Exercise in Debugging
Learn how to fix bad request / CSRF token missing errors with Flask that stem from bugs with webkit based browsers.
I am trying to login using the package and I was successful with Vue running on laratesting:8080 and laratesting:8081 it logins, gives the correct csrf tokens and subsequent requests are working fine. What I am trying to achieve, API: api.laratesting Vue: app.laratesting. I am sending a request to laravel from app.laratesting to api.laratesting. CSRF (Cross-site request forgery) is type of attack, when attacker tries to send malicious requests from a website that user visits to another site where the victim is authenticated. Prevention from this attack is based on keeping security token during user’s session and providing it with every modify operation (PUT, POST, DELETE).
There may come a time in your life where you’re absolutely sure that you have Flask-WTF configured properly in your application.
You Did Everything the Docs Stated
For starters, you’ve instantiated and exported
CsrfProtect like so:
You’ve also imported it into your
app.py file:
Then you’ve initialized it onto your Flask app:
Finally, you’ve included the proper tag in your form template:
Yet It Still Doesn’t Work and Flask Throws a CSRF Related Error
You may have tried to debug the issue by dropping this into your form’s route:
…and to your surprise the
csrf_token value is empty. WTF?
You’ve likely also opened your dev tools in your browser and went to the resources tab to take a look at your cookies. Oddly enough, it’s empty.
What Does Your Dev Environment Look Like?
Spotify download free dansk mac. Chances are 2 things are happening in your environment:
It may also be due to using an AWS EC2 instance’s public DNS hostname, but more on that later.
If your Flask server is not running on
localhost then in order to get Flask to resolve URLs properly, you’ve likely modified the SERVER_NAME value somewhere.
For example, you might have something like this in
config/settings.py :
This is what I recommend my students to do in the Build a SAAS App with Flask course if they happen to be using Docker Toolbox because we use Docker.
What Causes Bad Request CSRF Token Missing?![]()
This problem happens because of 2 things.
Firstly, there’s a bug in webkit based browsers.
The spec for rejecting cookies states that domain names must be a fully qualified domain name with a TLD (.com, etc.) or be an exact IP address.
Update in 2017: It looks like the spec has changed to explicitly state no exact IP addresses, so the bits about Chrome being buggy are no longer accurate.
Update in 20202: I recently discovered this also affects AWS EC2 public DNS hostnames. To be honest I’m not sure why they are treated as a direct IP address, but you will get a missing CSRF token error if you use your instance’s public DNS hostname.
Chrome is too cool to adhere to specifications, so they decided to be more strict and deny exact IP addresses. That means cookies won’t be set if you have an IP address based
SERVER_NAME .
Spotify Csrf Token
Ok, well that’s pretty lame but astute readers might be thinking how does
localhost work because that doesn’t include a TLD.
That brings us to the second thing, and we can blame Flask for that.
The Flask author is a very talented developer and 99.9% of the time his decisions are for your benefit but in my opinion he screwed up with this one.
If you look at the Flask source to return the cookie domain he makes assumptions about your development environment.
Take a look at this block of code:
The Flask author is definitely aware of the problem but he hard codes a fix. I can’t blame him because a lot of developers will be using
localhost so it fixes the problem for those developers without them having to think about it.
Nowadays Docker and virtualized development environments are much more common, so IMO I’d like to see this turned into a Flask config option so users can set which domain can get ignored.
Easily Fix the Problem for the Time Being
The quickest way to fix this problem in development would be to modify your
/etc/hosts file.
OSX and Linux users can find that in
/etc/hosts and Windows users can find it in C:WindowsSystem32driversetchosts .
You will need to open the file with elevated privileges, meaning you’ll need to open it with sudo or Administrator privileges.
Add this line to the bottom of the file:
192.168.99.100 local.docker
Keep in mind, if your development IP address is not what’s listed above then make the necessary adjustment to use yours instead.
Also feel free to change
local.docker to anything you want, as long as it includes a period so that it’s a valid FQDN with a TLD.
For example
local.dev or local.host would be valid but localfoo is not.
In the EC2 instance case, you should make a proper DNS entry on a real domain name and access your site there.
Updating Your Flask Config
The last thing you’ll need to do is change your
SERVER_NAME to match what we just created in the /etc/hosts file (or whatever your domain name is).
You’ll want to set:
SERVER_NAME = 'local.docker:8000' or whatever you used.
At this point you’re good to go and everything should work great.
An Exercise in Debugging
This was an interesting issue to debug because as you may know, I create video tutorials and courses.
I recently created a course on Flask and I personally run Docker on Linux natively. I also happen to use FireFox which does adhere to the spec correctly.
When I ran through the material, everything worked great but then issues started to pour in from OSX users. Some OSX users were using Docker Toolbox to set up their Docker environment, so they were using IP based server names.
However, not all OSX users were reporting this issue because not everyone was using Chrome and Docker Toolbox. Needless to say, it wasn’t an obvious solution, especially since I had students connect to my server through ngrok and successfully submit the form.
Where as, when I connected to their server it worked for me because I was using FireFox. Then when I tried Chrome on their server it failed, and that lead me to eventually tie in that the problem had something to do with Chrome.
Other students reported the same problem on Safari so it seems to affect webkit in general.
The lesson here is that you should take nothing for granted when it comes to debugging. Mov player for mac download. Even the slightest change in environment can cause drastic differences in output.
Learn how to fix bad request / CSRF token missing errors with Flask that stem from bugs with webkit based browsers.
There may come a time in your life where you’re absolutely sure that you have Flask-WTF configured properly in your application.
You Did Everything the Docs Stated
For starters, you’ve instantiated and exported
CsrfProtect like so:
You’ve also imported it into your
app.py file:
Then you’ve initialized it onto your Flask app:
Crack for izotope rx. Finally, you’ve included the proper tag in your form template:
Yet It Still Doesn’t Work and Flask Throws a CSRF Related Error
You may have tried to debug the issue by dropping this into your form’s route:
…and to your surprise the
csrf_token value is empty. WTF?
You’ve likely also opened your dev tools in your browser and went to the resources tab to take a look at your cookies. Oddly enough, it’s empty.
What Does Your Dev Environment Look Like?
Chances are 2 things are happening in your environment:
It may also be due to using an AWS EC2 instance’s public DNS hostname, but more on that later.
If your Flask server is not running on
localhost then in order to get Flask to resolve URLs properly, you’ve likely modified the SERVER_NAME value somewhere. Dev tools app for chrome on mac.
For example, you might have something like this in
config/settings.py :
This is what I recommend my students to do in the Build a SAAS App with Flask course if they happen to be using Docker Toolbox because we use Docker.
What Causes Bad Request CSRF Token Missing?
This problem happens because of 2 things.
Firstly, there’s a bug in webkit based browsers.
The spec for rejecting cookies states that domain names must be a fully qualified domain name with a TLD (.com, etc.) or be an exact IP address.
Update in 2017: It looks like the spec has changed to explicitly state no exact IP addresses, so the bits about Chrome being buggy are no longer accurate.
Update in 20202: I recently discovered this also affects AWS EC2 public DNS hostnames. To be honest I’m not sure why they are treated as a direct IP address, but you will get a missing CSRF token error if you use your instance’s public DNS hostname.
Chrome is too cool to adhere to specifications, so they decided to be more strict and deny exact IP addresses. That means cookies won’t be set if you have an IP address based
SERVER_NAME .
Ok, well that’s pretty lame but astute readers might be thinking how does
localhost work because that doesn’t include a TLD.
Dj app spotify pc. That brings us to the second thing, and we can blame Flask for that.
The Flask author is a very talented developer and 99.9% of the time his decisions are for your benefit but in my opinion he screwed up with this one.
If you look at the Flask source to return the cookie domain he makes assumptions about your development environment.
Take a look at this block of code:
The Flask author is definitely aware of the problem but he hard codes a fix. I can’t blame him because a lot of developers will be using
localhost so it fixes the problem for those developers without them having to think about it.
Nowadays Docker and virtualized development environments are much more common, so IMO I’d like to see this turned into a Flask config option so users can set which domain can get ignored.
Easily Fix the Problem for the Time Being
The quickest way to fix this problem in development would be to modify your
/etc/hosts file.
OSX and Linux users can find that in
/etc/hosts and Windows users can find it in C:WindowsSystem32driversetchosts .
You will need to open the file with elevated privileges, meaning you’ll need to open it with sudo or Administrator privileges.
Add this line to the bottom of the file:
192.168.99.100 local.docker
Keep in mind, if your development IP address is not what’s listed above then make the necessary adjustment to use yours instead.
Also feel free to change
local.docker to anything you want, as long as it includes a period so that it’s a valid FQDN with a TLD.
For example
local.dev or local.host would be valid but localfoo is not.
In the EC2 instance case, you should make a proper DNS entry on a real domain name and access your site there.
Updating Your Flask Config
The last thing you’ll need to do is change your
SERVER_NAME to match what we just created in the /etc/hosts file (or whatever your domain name is).
You’ll want to set:
SERVER_NAME = 'local.docker:8000' or whatever you used.
At this point you’re good to go and everything should work great.
An Exercise in Debugging
This was an interesting issue to debug because as you may know, I create video tutorials and courses.
I recently created a course on Flask and I personally run Docker on Linux natively. I also happen to use FireFox which does adhere to the spec correctly.
Invalid Csrf Protection Token
When I ran through the material, everything worked great but then issues started to pour in from OSX users. Some OSX users were using Docker Toolbox to set up their Docker environment, so they were using IP based server names.
However, not all OSX users were reporting this issue because not everyone was using Chrome and Docker Toolbox. Needless to say, it wasn’t an obvious solution, especially since I had students connect to my server through ngrok and successfully submit the form.
Csrf Token Invalid Spotify App Password
Where as, when I connected to their server it worked for me because I was using FireFox. Then when I tried Chrome on their server it failed, and that lead me to eventually tie in that the problem had something to do with Chrome.
Csrf Token Error
Other students reported the same problem on Safari so it seems to affect webkit in general.
Spotify Csrf Token Invalid
The lesson here is that you should take nothing for granted when it comes to debugging. Even the slightest change in environment can cause drastic differences in output.
Comments are closed.
|
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |