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 GET for reading data and POST for creating data

  • require 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.3. Authentication and Authorisation#

Authentication identifies who is making the request. Authorisation decides what that user is allowed to do.

A safe API should apply least privilege: every user, token, and service should have only the permissions it needs. For example, a normal user might be allowed to read their own profile but not read every user’s profile or change another user’s role.

Common API access controls include:

  • requiring login or an API token

  • checking roles or permissions before changing data

  • expiring tokens or sessions after a suitable time

  • using HTTPS so tokens and cookies are not sent in plain text

  • recording important actions in logs

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 Request can be used when JSON is missing or invalid

  • 401 Unauthorized can be used when the request is not authenticated

  • 403 Forbidden can be used when the user is authenticated but not allowed to perform the action

  • 404 Not Found can 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.

5.5.6. Glossary#

Least privilege#

A security principle where users, programs, and services receive only the permissions they need to complete their task.

Rate limiting#

Restricting how many requests a client can make in a period of time.