Skip to main content

CSRF troubleshooting

When you get 401 Unauthorized or 400 Bad Request responses when your application sends requests to Ory Identities APIs, it is likely that the Ory anti-Cross-Site Request Forgery (CSRF) mechanisms are triggered.

This document describes common scenarios where you can face CSRF problems and gives advice for solving them.

What is CSRF?

As defined by OWASP, "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."

tip

To learn more about CSRF, read the OWASP attack description

To protect against these attacks, many Ory Identities API endpoints are protected by anti-CSRF measures. These are mainly the endpoints that accept the POST, DELETE, or PUT methods. For example, when an app renders a form, a <input type="hidden" name="csrf_token" value="..."> HTML input element is added. Ory Identities compares that value to the value set in the anti-CSRF cookie. If the values match, the request is allowed.

info

Ory Identities uses HTTP cookies to store sessions when accessed via a browser. Learn more about the cookie-based security model in Ory.

How to debug

To debug issues related to cookies or anti-CSRF defenses, use tools like the Chrome DevTools. In Chrome DevTools, go to the Application tab and open the Cookies section. Look for Cookie and Set-Cookie HTTP headers. Inspecting the Network tab and looking for the same headers can also help you find the root cause of your problems.

Accessing cookies from client-side JavaScript

The cookies Ory Identities sets can't be accessed directly from client-side JavaScript because the HttpOnly flag is set. This flag can't be modified.

Accessing APIs from client-side JavaScript / AJAX

When building Single-Page Apps (SPAs) in Angular or React.js and you want the application to access the Ory Identities Public API you need to configure your AJAX request to include cookies, because AJAX doesn't send cookies by default default.

For example, when using the browser's fetch function, you need to set credentials: 'include'.

Accessing APIs from a server-side application

When building a server-side application, make sure to include the Cookie header from the client when fetching the self-service flows, for example, GET /self-service/login/flows?id=...:

export default (req: Request, res: Response) => {
// ...
.getLoginFlow({ id: flow, cookie: req.header("cookie") })
}

A complete example looks as follows:

https://raw.githubusercontent.com/ory/kratos-selfservice-ui-node/master/src/routes/login.ts

Without forwarding the Cookie HTTP header you can't fetch the flow due to a security error. This prevents leaks of personal information when users copy and paste, for example, the login URL.

Further reading

Read this document for CRSF troubleshooting specific to self-hosted Ory Kratos Identity Server instances.