vimalloc/flask-jwt-extended

CSRF still required for optionally authenticated endpoints

ngetahun opened this issue ยท 2 comments

Hey,

Thanks for maintaining this library ๐Ÿ’œ . My rest api has CSRF protection enabled but I'm working on a new feature where a front end client can access an endpoint without any auth, @jwt_required(optional=True). I keep getting a 401 response with "Missing CSRF token" errors. Shouldn't optional jwt validation exempt from csrf validation as well? I might be very wrong on this one but would appreciate any help as I see no way around this issue.

Setup:
Flask-JWT-Extended == 4.2.3
Flask == 2.1.3

What an interesting use case! Generally you want CSRF protection in place for anything that modifies application state (POST/PUT/DELETE/etc) to prevent vulnerabilities in your application, but on the flip side generally those actions are generally locked behind some sort of authentication/authorization layer so that not just anyone can perform them. If that endpoint is open to the world and anyone can perform it, then you don't really need to use a CSRF vector to hit that endpoint in the first place.

I'm inclined to say that if an endpoint has @jwt_required(optional=True) and a JWT is in the request, the CSRF protection should still be in place, so that the endpoint is not vulnerable to a CSRF attack from a given logged in user. However, if it is hit without a JWT in the request, no CSRF protection should be performed. Glancing at the code, I believe this is how the current behavior should be working. Can you tell me if you are experiencing different behavior?

If you can tell me a little bit more about how you hitting this endpoint I could see if anything springs to mind for how to best solve the problem you're running into.

Cheers!

IMO as mentioned by @vimalloc CSRF must be required (at least if you accept the risk and deactivate CSRF via JWT_COOKIE_CSRF_PROTECT) even when JWT is optional, to avoid any attack.