Search code examples
djangodjango-csrfcsrf-protection

Safety of disabling CSRF protection for API acces in django


(Apologies if all this sounds trivial, I am a beginner both with web programming and django)

I am writing a web frontend to a database of scientific measurements with django.

Part of the needed functionality is to give users the ability to submit new measurements to the database from a webpage. I have this piece of functionality working with the help of django's excellent support for web forms. Data is sent via POST requests protected by CSRF tokens.

I am now developing the same functionality not via web forms, but via API access, so that users can do, e.g., bulk submissions of new measurements via a Python script without having to fill out a web form each time by hand.

The problem with this is that, since there is no form to fill out, there is no CSRF token as well and django does not allow by default to send POST requests without it.

For now, I have worked around the problem by decorating the API view with @csrf_exempt. But I do not really understand the security implications of doing so.

Could this be a security risk? If so, how?


Solution

  • It defiantly is a security risk, as any site/script/bot can then send POST data that will be processed by your backend.

    If you looking to provide a public/anonymous API, then its likely fine, you just need to be extra careful how you process the received data.

    If you are looking to provide users/specific apps access, then you should keep the CSRF token and/or add some other security measure.

    with CSRF tokens, all you need to do is have the first request to the system be a "GET" request that authenticates a user (in whatever way you want) and would then return a CSRF token (or some other security token if you want to enhance the security).

    then all further requests to your API (for whatever session length you have set, as the CSRF token will expire in a specific unused time frame). Simply sends the CSRF token with the POST data (like any form does).

    EDIT:

    If you are using standard HTML, all get Requests will have a Header "Set-Cookie" that contains the CSRFTOKEN. So any program accessing your API via HTTP, can get that header, parse the CSRFTOKEN out of it, and return in on all POST requests as part of the dataset.