Version 5 supported

Security & best practices

Cross-Origin Resource Sharing (CORS)
Ensure that requests to your API come from a whitelist of origins
Authentication
Ensure your GraphQL api is only accessible to provisioned users
Strict HTTP method checking
Ensure requests are GET or POST
Recursive or complex queries
Protecting against potentially malicious queries
CSRF protection
Protect destructive actions from cross-site request forgery

CSRF tokens (required for mutations)

Even if your GraphQL endpoints are behind authentication, it is still possible for unauthorised users to access that endpoint through a CSRF exploitation. This involves forcing an already authenticated user to access an HTTP resource unknowingly (e.g. through a fake image), thereby hijacking the user's session.

In the absence of a token-based authentication system, like OAuth, the best countermeasure to this is the use of a CSRF token for any requests that destroy or mutate data.

By default, this module comes with a CSRFMiddleware implementation that forces all mutations to check for the presence of a CSRF token in the request. That token must be applied to a header named X-CSRF-TOKEN.

In Silverstripe CMS, CSRF tokens are most commonly stored in the session as SecurityID, or accessed through the SecurityToken API, using SecurityToken::inst()->getValue().

Queries do not require CSRF tokens.

Disabling CSRF protection (for token-based authentication only)

If you are using HTTP basic authentication or a token-based system like OAuth or JWT, you will want to remove the CSRF protection, as it just adds unnecessary overhead. You can do this by setting the middleware to false.

SilverStripe\Core\Injector\Injector:
  SilverStripe\GraphQL\QueryHandler\QueryHandlerInterface.default:
    class: SilverStripe\GraphQL\QueryHandler\QueryHandler
    properties:
      Middlewares:
        csrf: false

Further reading

Cross-Origin Resource Sharing (CORS)
Ensure that requests to your API come from a whitelist of origins
Authentication
Ensure your GraphQL api is only accessible to provisioned users
Strict HTTP method checking
Ensure requests are GET or POST
Recursive or complex queries
Protecting against potentially malicious queries
CSRF protection
Protect destructive actions from cross-site request forgery