Preventing Production API Abuse


Payload has built-in security best practices that can be configured to your application-specific needs.

Limit Failed Login Attempts

Set the max number of failed login attempts before a user account is locked out for a period of time. Set the maxLoginAttempts on the collections that feature Authentication to a reasonable but low number for your users to get in. Use the lockTime to set a number in milliseconds from the time a user fails their last allowed attempt that a user must wait to try again.

Rate Limiting Requests

To prevent DDoS, brute-force, and similar attacks, you can set IP-based rate limits so that once a certain threshold of requests has been hit by a single IP, further requests from the same IP will be ignored. The Payload config rateLimit property accepts an object with the following properties:

windowTime in milliseconds to track requests per IP
maxNumber of requests served from a single IP before limiting
skipExpress middleware function that can return true (or promise resulting in true) that will bypass limit
trustProxyTrue or false, to enable to allow requests to pass through a proxy such as a load balancer or an nginx reverse proxy

Max Depth

Querying a collection and automatically including related documents via depth incurs a performance cost. Also, it's possible that your configs may have circular relationships, meaning scenarios where an infinite amount of relationships might populate back and forth until your server times out and crashes. You can prevent any potential of depth-related issues by setting a maxDepth property on your Payload config.. The maximum allowed depth should be as small as possible without interrupting dev experience, and it defaults to 10.

Cross-Site Request Forgery (CSRF)

CSRF prevention will verify the authenticity of each request to your API to prevent a malicious action from another site from authorized users. See how to configure CSRF here.

Cross Origin Resource Sharing (CORS)

To securely allow headless operation you will need to configure the allowed origins for requests to be able to use the Payload API. You can see how to set CORS as well as other payload configuration settings here

Limiting GraphQL Complexity

Because GraphQL gives the power of query writing outside a server's control, someone with bad intentions might write a maliciously complex query and bog down your server. To prevent resource-intensive GraphQL requests, Payload provides a way specify complexity limits which are based on a complexity score that is calculated for each request.

Any GraphQL request that is calculated to be too expensive is rejected. On the Payload config, in graphQL you can set the maxComplexity value as an integer. For reference, the default complexity value for each added field is 1, and all relationship and upload fields are assigned a value of 10.

If you do not need GraphQL it is advised that you disable it altogether with the Payload config by setting graphQL.disable: true. Should you wish to enable GraphQL again, you can remove this property or set it false, any time. By turning it off, Payload will bypass creating schemas from your collections and will not register the express route.


The Payload License