CSRF cookies #291
Replies: 13 comments 12 replies
-
If you're able to, it may be beneficial to add documentation on manually adding a user via the Databases package in a similar way to how you do in the /register endpoint for people who would like to automatically generate an admin user if there currently are none. |
Beta Was this translation helpful? Give feedback.
-
As far as the db stuff goes, this is what I have for creating a new user in a similar way to how the /register endpoint does. Please let me know if there's something wrong with doing things this way. from .auth import fastapi_users, get_auth_router, cookie_authentication, database, users, user_create, UserDB, get_password_hash #this is the file that fastapi-users is initialized in.
@app.on_event("startup")
async def startup():
await database.connect()
users_exist = await database.fetch_all(query=users.select())
if users_exist:
print("users exist")
else:
print("no users")
hashed_password = get_password_hash(settings.ADMIN_PASSWORD)
base_user = UserDB(
id = uuid.uuid4(),
email = settings.ADMIN_EMAIL,
hashed_password = hashed_password,
is_active = True,
is_superuser = True
)
user_created = await user_create(base_user) This is a function in the auth.py file that just exposes the same function that you use for the /register endpoint. async def user_create(UD):
await fastapi_users.db.create(UD) |
Beta Was this translation helpful? Give feedback.
-
Hi @SelfhostedPro! I don't see anything wrong with the code you are showing ; even if I still personally think it's better to set the superuser flag manually from the database ; but that's okay! As for the CSRF, I'll look further into it, thanks! |
Beta Was this translation helpful? Give feedback.
-
I just discovered this project: https://github.com/simonw/asgi-csrf It's an ASGI middleware that handles CSRF protection. I'll look into this, but I think this would allow to implement this security without having to implement it in |
Beta Was this translation helpful? Give feedback.
-
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Beta Was this translation helpful? Give feedback.
-
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Beta Was this translation helpful? Give feedback.
-
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Beta Was this translation helpful? Give feedback.
-
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Beta Was this translation helpful? Give feedback.
-
Is there a way to disable the stale bot on a specific issue? That looks like it would work. It's unfortunate that they haven't responded to your issue though. |
Beta Was this translation helpful? Give feedback.
-
Sorry! I didn't pay attention! |
Beta Was this translation helpful? Give feedback.
-
This got me interested in reading up on CSRF, and I thought it might be helpful to share what I learned as far as FastAPI-Users is concerned. In short, it seems that FastAPI-Users is mostly secure against CSRF already. Routes that are potential targets:
Using CSRF Tokens would also protect these routes, but could be a bit tricky to implement. Unfortunately, the asgi-csrf middleware wouldn't work for this case. The problem is that you have to have a way of communicating the CSRF Token to the client that the attacker can't see, and then all forms/api clients will have to send the token. As mentioned, flask-jwt-extended accomplishes this by setting a cookie. The client would then have to read the cookie and submit the token in a separate header (that's what double submit means: the csrf token is sent back to the server both as a cookie, and manually in a custom header). Since a third-party attacker couldn't read the token in the cookie, only JS that came from the same origin would be able to submit the custom header. The answer to this question goes over several ways that the CSRF Token can safely be communicated between the client and server, which I found helpful in understanding how it works: https://stackoverflow.com/questions/20504846/why-is-it-common-to-put-csrf-prevention-tokens-in-cookies Here are the routes that are definitely already secure against CSRF.
Routes that don't change state on the server:
|
Beta Was this translation helpful? Give feedback.
-
Thanks for the response, and no problem about the delay. I've been offline for awhile, myself. Definitely, routes using the dependencies could be vulnerable to CSRF. I feel like adding CSRF Tokens would be a lot of effort with little payoff, though. Considering that the cookies are already being set with the Beyond that, even if CSRF Tokens are implemented in FastAPI-Users, the end-developer will still have to do the work on the frontend to support it. And if they're already doing that, it should be easy to just drop in something like the asgi-csrf middleware. I'm not saying it would be a bad idea to add this feature, or that it wouldn't be useful to anybody, only that it might not be worth your time. But only you can really decide that, of course. If you still want to do it, I'd be happy to help in any way I can. |
Beta Was this translation helpful? Give feedback.
-
Hey there! A long time since we discussed this subject 😄 After some extensive research, it appears that it's still strongly recommended nowadays to have a CSRF protection besides I gave a shot at implementing a middleware for Starlette/FastAPI implementing the double-submit cookie technique: https://github.com/frankie567/starlette-csrf I wanted to make it easy to understand and configure. Would be glad to have your feedbacks 😄 |
Beta Was this translation helpful? Give feedback.
-
Hi, I think it would be beneficial to include csrf cookies along with the standard jwt cookies in order to help prevent your jwt tokens from getting stolen.
You can see what flask-jwt-extended does here: https://github.com/vimalloc/flask-jwt-extended/blob/5bd8b1ed08ea64d23869a629af3c3c868816b8a8/flask_jwt_extended/utils.py#L260
Beta Was this translation helpful? Give feedback.
All reactions