5.5. Safe APIs#
An API lets software interact with another application or service. A REST API does this over HTTP using predictable endpoints, methods, and JSON data.
A safe API is designed so that clients can do only what they are allowed to do, with only the data they need, in a way that does not expose the rest of the system.
5.5.1. Designing Safe Endpoints#
Each API endpoint should have a clear purpose. Developers should avoid creating overly powerful endpoints that perform many different actions based on user input.
For example, an endpoint such as POST /admin/run would be risky if the
client can send arbitrary commands. A safer design uses specific endpoints with
specific permissions, such as POST /users/42/reset-password.
When designing endpoints:
use the correct HTTP method for the action, such as
GETfor reading data andPOSTfor creating datarequire authentication for private or account-specific data
check authorisation for every request, even if the user is already logged in
avoid exposing internal database IDs, file paths, stack traces, or secrets
return only the fields the client needs
5.5.2. Validating API Requests#
API input should not be trusted. Attackers can send requests directly to an API without using the website or app interface that normal users see.
Safe APIs should validate:
required fields
data types, such as strings, numbers, booleans, and lists
lengths and ranges, such as maximum username length or allowed quantity values
allowed values, such as a known list of roles or status names
JSON structure
APIs that use databases should use parameterised queries or a trusted ORM rather than building queries with string concatenation. This helps prevent SQL injection.
5.5.4. Limiting Abuse#
Even valid endpoints can be misused. For example, an attacker might try many passwords, scrape private data, or send thousands of requests to slow the system.
Rate limiting restricts how many requests a client can make in a period of time. Other controls include pagination for large results, maximum upload sizes, and rejecting requests that are too large or too frequent.
5.5.5. Safe Error Responses#
API error messages should help legitimate developers fix their requests without revealing sensitive implementation details.
For example:
400 Bad Requestcan be used when JSON is missing or invalid401 Unauthorizedcan be used when the request is not authenticated403 Forbiddencan be used when the user is authenticated but not allowed to perform the action404 Not Foundcan be used when a resource does not exist or should not be revealed to that user
Avoid returning stack traces, SQL errors, file paths, secret keys, or detailed information about whether a username or account exists.