Ajax POST fails to due missing CSRF token - django

I've got a rather odd problem. I've got probably 100s of ajax calls back to my backend. They all work except for one. For some reason, on one page that doesn't require that the user be logged in to access (but can be logged in when they access the page), the ajax query fails due to missing CSRF token. When I clear history/cookies in Chrome, the ajax call is successful.
Any thoughts on what could be causing this?
Thanks!

Related

How to send a POST request with Postman through Spring's CSRF

So, I am developing a very basic blog using spring boot, and as I am getting to the controllers layer, I want to test with Postman. GET requests are working perfectly fine, but POST requests are getting 403 forbidden.
I have been doing a lot of research and it seems it is all about the default spring security's CSRF cookie. I have tried a bunch of different things (like this one https://dev.to/shane/using-postman-with-java-spring-and-csrf-tokens-di0), but the thing is, when I do it, the csrf variable in Postman never gets filled. It is always undefined.
On the other hand, I know there are ways to disable csrf, but I don't want that. It does not solve anything, it is just bypassing the problem without really understanding how to tackle it.
How can I get past this? How can I get Postman to get the csrf cookie, put it in a variable that I can then reuse in a POST request?

Is generating CSRF token on the front-end a bad idea?

In Django world, CSRF token is generated in a way that doesn't involve any information known only to the server. It's perfectly possible to generate a valid CSRF token in javascript - Django will happily accept it.
In particular, one could have a piece of javascript that generates valid CSRF token and sets it as a cookie (and it will work fine because of the same origin).
Are there any security related drawbacks of doing that? The only thing I can think of is that such cookie cannot have the http-only flag set (for obvious reasons).
The short answer is No
CSRF is a solution to restrict CSRF attacks. So in the server, a code is generated (and signed) to check is user using built-in js codes or not. for example, a user can call a function without CSRF protection in the browser console or with a browser extension or with curl without any browser, in this condition, you cannot understand is user knows this function call or not!
On the other side, you want to make a new CSRFTOKEN and send it to the server with ajax and this service cannot protect with CSRF. So the hackers can use this ajax call for CSRF forgery! And the hacker can find your CSRF maker code in your js libraries.
For your Idea, you can use some user info and save it in session info such as use-agent, client-IP, and ...

Is it okay to disable CSRF for slack slash command api mad in Django?

Is it disabling CSRF functionality the best practice for Slack slash command server?
I want to call an API view function in Django by a Slack slash command, for example, /test.
When I call the URL for the view function with any browser (so it is a GET request), it works as expected.
However, when I run /test in Slack, I got 403_client_error in slack, and Forbidden (CSRF cookie not set) in the Django shell.
I believe this is because Slack sends a POST request, and Django requires CSRF token for any POST requests.
My question is whether I should disable CSRF checking for this view. Will there be a significant risk? Or is there any workaround?
Short Answer:
Yes, it's fine for an API endpoint.
Longer Answer:
Cross-Site Request Forgery (CSRF) Tokens are a means of preventing CSRF Attacks. These attacks basically work by placing some malicious code on another site that runs when the user visits that site. Upon loading the malicious site, some JavaScript code runs and submits a POST request to a site that the victim is already authenticated at. Since the user is already authenticated, the server for the other site—a bank, for example—thinks that the user is actually making this request—send the attacker $100, for example—and goes ahead and processes the request. Here is a really good description of CSRF Attacks and Tokens: https://stackoverflow.com/a/33829607/8068625
The way that CSRF Tokens prevent this is by putting a token somewhere on any page that contains a form and that token gets submitted as an additional field on the form when submitted. This way the page must actually be visited (which the attacker should not be able to accomplish) in order to submit the page.
So, as long as this page you are removing the CSRF protection from does not have a form on it that you would not like submitted by an attacker, it is fine to add #csrf_exempt to the view. It seems that this is the case since the endpoint exists solely as an API endpoint for a Slack Slash Command.
You might consider adding some other form of authentication for your API endpoints (note that CSRF is not for use in APIs) like, for example, JSON Web Tokens. But that is up to you.

Flask login "remember_me" does not work with Flask-WTF CSRF

I've been scratching my head for the last couple days, trying to figure out an appropriate fix for this issue.
I'm using Flask-Login with Flask-WTF. Upon logging in, I am able to submit all POST requests to CSRF protected forms through Flask-WTF, and everything works as expected.
However, if "Remember_Me" has been set (thus placing a remember me cookie on the client side) and a close and restart my browser, on visiting the form two things happen:
1 - Flask Login captures from the remember me cookie, correctly logging
in and authenticating.
2 - Attempmting to POST any data, either Ajax or
through a form, Flask-WTF fails CSRF validation, due to line 86 in
Flask-WTF/csrf.py
if field_name not in session:
raise ValidationError('The CSRF session token is missing.')
This is I'm guessing expected behaviour, as the session token doesn't theoretically exist for a remembered session, as Flask-Login pulls the user ID out of the remember_me cookie.
Anyone come across this issue at all? I have no idea how to go about sorting this - I don't want to disable CSRF protection, nor allowing remember_me tokens.
Is there some way I can refresh the session token on successful retrieval from the cookie?

Cannot retrieve image in browser when using OAuth token and Jira

I am building a frontend client for Jira and am running into some conflicting authentication methods I think.
I have setup the OAuth2 authentication method for logging in and hitting the Jira API. I have a button on a login page that redirects to Jira, you log in, hit "allow" and are redirected to my app. This step completes fine, I have a token and a secret and can make api calls just fine.
Next, I make an api call to get the user data, which returns fine. One of the pieces of data is a set of avatar urls. I put one of the urls into my site's markup. Here is where the problem begins.
If my browser session that I used to login is still active, I get an avatar. BUT if not, I get an "anonymous" avatar from Jira.
All the while, my OAuth token/api calls all seem to return fine.
This makes sense as Jira is using cookie based auth and I am not. So if that cookie dies in my browser, the call to the image will fail.
My ultimate question is how to handle this? Is this my responsibility to put an expiration on the token? What happens if they select "Stay logged in"? I don't think I get that knowledge on the OAuth side.
I kind of feel like I am missing something but I cannot figure out what. This seems like a problem that has been fixed or isn't even really a problem.
One solution would be just to switch to a cookie based authentication but OAuth seems more secure.
I've also tried directly hitting it from my server but that also yields an anon avatar. As does a curl with the access token. Maybe I didn't provide it in the correct way?
Any thoughts or ideas on this would be greatly appreciated. Thanks in advance.