How does CSRF token work? SAP Gateway
Update 2021-06-25: making the diagrams more precise & explicitly writing that the CSRF token is for one user session.
Update 2021-09-28: explaining cookies in more detail.
“Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated.” OWASP Cross Site Request Forgery (CSRF)
Issues come really often about CSRF token validations where developers receive errors like:
403 Forbidden CSRF Token required
403 Forbidden CSRF Token expired
The aim of this Blog is to explain how CSRF token protection works in SAP Gateway and how should developers implement it.
The ideal flow is like the following:
- The client application sends a GET request with header X-CSRF-TOKEN: Fetch (this is usually sent in the $metadata or in a simple service document request).
- The server then responds with 200 OK and response header: X-CSRF-TOKEN: <tokenValue> and one or more Set-Cookie headers (not highlighted below)
- The client has to store this token and all the cookies in the Set-Cookie response header (the cookie here identifies the HTTP session) and send in every modification request* throughout its session. When the session renews the CSRF token has to be renewed as well, by requesting a token again.
*A modification request, is a non-GET request like POST, PUT, PATCH, MERGE, DELETE (CUD). Note, that $batch requests are always sent with POST method.
- The server will check this token and the session ID cookie(s) and if they’re valid and matching, it’ll process the request. If at least one of them is invalid or expired then the server will respond with 403 Forbidden, with response header: X-CSRF-TOKEN: Required, with response body: “CSRF Token required”
- The client has to automatically send a new GET request with X-CSRF-TOKEN: Fetch and retrieve the new token from the response header.
So the successful scenario would look like this (Set-Cookie + Cookie isn’t present in the diagram):
And the scenario where it fails once and the client has to re-request the CSRF token would look like this (Set-Cookie + Cookie isn’t present in the diagram):