[graphiql] Add cookie-to-header token CSRF support #3355
-
I would like to have Cookie-to-header CSRF tokens as an default feature in GraphiQL. I'm working on an Angular based SPA with a Spring Boot backend. GraphiQL can be activated in Spring by simply changing a boolean flag. Sadly, when using Spring Security with CSRF protection to secure my endpoints, GraphiQL cannot be used anymore, because it does not set the X-CSRF-TOKEN nor the X-XSRF-TOKEN header as Angular for example does automatically. Therefore, CSRF protection for the GraphQL endpoint must be disabled when GraphiQL is active. The only solutions that I found online completely disabled CSRF in Spring. Since I don't want to do that I disabled it on the GraphQL path while developing. This isn't a great solution and if done wrong, it would disable CSRF for GraphQL in production as well. But if I don't do that, than I cannot use GraphiQL out of the box. So in order to increase the security of future GraphQL endpoints, I would like to request the same CSRF cookie-to-header automation that Angular provides for GraphiQL. |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments
-
This is already possible, I can provide an example if you like? |
Beta Was this translation helpful? Give feedback.
-
Sure, that would be great. |
Beta Was this translation helpful? Give feedback.
-
I haven't worked with angular in a while, so I will just give you a vanilla example. this also assumes you aren't processing react JSX and are following something like the CDN example. this also assumes the cookie is already set when accessing the graphiql instance. We've used this approach at several companies that used CSRF tokens and/or JWT with cookies const headers = ''
if (typeof window !== undefined) {
// maybe angular has a utility for accessing cookies?
const getCookie = name => document.cookie.match(new RegExp(`(^| )${name}=([^;]+)`))?.at(2);
const value = getCookie('CSRF COOKIE NAME')
headers = `{ "X-CSRF-TOKEN" : "${value}" }`
}
const root = ReactDOM.createRoot(document.getElementById('graphiql'));
root.render(
React.createElement(GraphiQL, {
fetcher: GraphiQL.createFetcher({
url: '/graphql,
}),
// pass the headers prop programattically
headers
}),
); |
Beta Was this translation helpful? Give feedback.
-
Thanks for the example. That's why I opened this issue, because I think others could provit as well if GraphiQL provides this out of the box as Angular does. On the other hand it might be more related to the Spring package not including this in the first place, so maybe my request would be more fitting over there. Even though this security feature has nothing to do with Spring in particular. |
Beta Was this translation helpful? Give feedback.
-
@Kaemmelot indeed, it may be best to make this feature request to spring's graphql implementation you are using - usually each framework and/or platform implements it's own client authn for graphiql. there are many flavors, headers and cookie names used, etc. there is a plugin API as well that may be of help |
Beta Was this translation helpful? Give feedback.
I haven't worked with angular in a while, so I will just give you a vanilla example. this also assumes you aren't processing react JSX and are following something like the CDN example. this also assumes the cookie is already set when accessing the graphiql instance. We've used this approach at several companies that used CSRF tokens and/or JWT with cookies