fastapi icon indicating copy to clipboard operation
fastapi copied to clipboard

built-in CSRF protect

Open Niccolum opened this issue 2 years ago • 5 comments

First Check

  • [X] I added a very descriptive title to this issue.
  • [X] I used the GitHub search to find a similar issue and didn't find it.
  • [X] I searched the FastAPI documentation, with the integrated search.
  • [X] I already searched in Google "How to X in FastAPI" and didn't find any information.
  • [X] I already read and followed all the tutorial in the docs and didn't find an answer.
  • [X] I already checked if it is not related to FastAPI but to Pydantic.
  • [X] I already checked if it is not related to FastAPI but to Swagger UI.
  • [X] I already checked if it is not related to FastAPI but to ReDoc.

Commit to Help

  • [X] I commit to help with one of those options 👆

Example Code

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.post("/")
def post_root():
    with open("some_data", 'w') as f:
        f.write("superimportant_data")

Description

Now we have plugin fastapi_csrf_protect, but it looks like strange. Just see code here:

https://www.stackhawk.com/blog/csrf-protection-in-fastapi/

Wanted Solution

Feature request for built-in csrf settings, which will looks like cors - as middleware.

Just something like https://github.com/frankie567/starlette-csrf, but built-in fastapi

Wanted Code

from fastapi import FastAPI
from fastapi.middlewares import CSRFMiddleware

from app.core import app_config

app = FastAPI()
app.add_middleware(CSRFMiddleware, secret="__CHANGE_ME__")

@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.post("/", csrf_token=True) # by default
def post_root():
    with open("secure_file", 'w') as f:
        f.write("superimportant_data")

@app.post("/access_post_without_csrf/", csrf_token=False) 
    with open("unsecure_file", 'w') as f:
        f.write("some_data")

Alternatives

https://github.com/frankie567/starlette-csrf

Operating System

Linux, Windows, macOS

Operating System Details

No response

FastAPI Version

latest

Python Version

3.10.1

Additional Context

No response

Niccolum avatar Jan 12 '22 20:01 Niccolum

~~FastAPI community is welcome to use my code: https://github.com/gnat/csrf-starlette-fastapi/blob/main/csrf_middleware.py~~

~~50 lines.~~

See: https://github.com/gnat/csrf-starlette-fastapi#why-you-may-not-need-a-csrf-middleware-in-2022

gnat avatar Jan 29 '22 02:01 gnat

FastAPI community is welcome to use my code: https://github.com/gnat/csrf-starlette-fastapi/blob/main/csrf_middleware.py

~50 lines.

It's good, that you have your own implementation. But I said about built-in support. How it's important we can see in similar issue in starlette, which now is discussion. https://github.com/encode/starlette/discussions/1411

Niccolum avatar Jan 29 '22 09:01 Niccolum

+1. This will be a really good enhancement for the framework

BigSamu avatar Jul 21 '22 21:07 BigSamu

Update- why you don't need a middleware for CSRF in 2022: https://github.com/gnat/csrf-starlette-fastapi#why-you-may-not-need-a-csrf-middleware-in-2022

tl;dr: Browsers have improved enough that you can use a dual-cookie system: one lax, one strict.

gnat avatar Jul 21 '22 22:07 gnat

@gnat it's okay for newer browsers. What about older?

Also, not protected with subdomain attack

Niccolum avatar Aug 09 '22 20:08 Niccolum