Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a security section warning about CSRF #64

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,16 @@ Charlie file content.
--------------------------627436eaefdbc285--
```

## Security

Most HTTP GraphQL servers will only execute mutations when they are provided in `POST` requests, and servers that do not implement the GraphQL multipart request spec typically only process `POST` requests with `content-type` headers such as `application/json` or `application/graphql`. Because of this, most GraphQL servers that do not implement this protocol will never execute a mutation inside a ["simple request"](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests), and so mutations cannot be executed by Cross-Site Request Forgery (CSRF) attacks.

However, servers that implement the GraphQL multipart request spec will execute GraphQL operations provided as `POST` requests with `Content-Type: multipart/form-data`. This content-type is special-cased in browser security and (unlike `application/json`) requests with this content-type can be "simple". This means that unless other mitigations are provided, servers implementing the GraphQL multipart request spec will be vulnerable to CSRF attacks that execute mutations.

If you implement this protocol in your server, then you should ensure that your server is not vulnerable to CSRF attacks. Approaches include:
- Refuse to execute GraphQL operations from any HTTP request that does not contain some non-empty header that browsers will not send by default, such as `GraphQL-Require-Preflight`. Setting such a header means that the request is no longer a simple request. (If you are careful to parse `Content-Type` in the same way that browsers parse it, you only need to require this header for requests that have no `Content-Type` or set one of three particular content-types including `multipart/form-data`.) For example, if every operation must already have some sort of custom API key header, then you are already protected against CSRF attacks.
- Avoid the use of cookies, HTTP Basic Authentication, and network separation for security. Publicly accessible web servers which do not use an authentication mechanism that is automatically added by browsers typically are immune to CSRF, because any operation that untrusted browser JS could execute could also just be run directly by the attacker outside of the browser.

## Implementations

Pull requests adding either experimental or mature implementations to these lists are welcome! ~~Strikethrough~~ means the project was renamed, deprecated, or no longer supports this spec out of the box (but might via an optional integration).
Expand Down