Get a Pentest and security assessment of your IT network.

Cyber Security

Secure API Best Practices

TL;DR

This guide covers essential steps to build a relatively simple but secure API for your clients. We’ll focus on authentication, input validation, rate limiting, and basic error handling.

1. Authentication & Authorisation

How do you know who is using your API? Authentication verifies identity; authorisation determines what they can access.

  1. API Keys: A simple starting point. Generate a unique key for each client. Store these securely (see section 5).
    • Include the API Key in every request, typically as an HTTP header (e.g., X-API-Key) or query parameter.
    • curl -H "X-API-Key: YOUR_API_KEY" https://your-api.com/data
  2. Consider OAuth 2.0: For more complex scenarios (user accounts, delegated access), OAuth 2.0 is a better choice. It's more secure and flexible but requires more setup.
  3. Never store passwords directly: Use strong hashing algorithms like bcrypt or Argon2.

2. Input Validation

Don’t trust user input! Always validate everything before processing it to prevent attacks like SQL injection and cross-site scripting (XSS).

  1. Whitelisting: Define what is *allowed* rather than trying to block bad things.
  2. Data Types: Ensure data matches the expected type (e.g., integer, string, email address).
  3. Length Restrictions: Limit input lengths to prevent buffer overflows and denial-of-service attacks.
  4. Regular Expressions: Use regex for complex patterns like email validation or phone numbers.
    • Example (Python):
      import re
      if re.match(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$"; email):
        # Valid email address
      else:
        # Invalid email address

3. Rate Limiting

Protect your API from abuse by limiting the number of requests a client can make within a certain timeframe.

  1. Identify Clients: Use IP address, API key, or user ID to track request rates.
  2. Set Limits: Define appropriate limits based on your API's resources and expected usage (e.g., 100 requests per hour).
  3. Return Error Codes: Respond with a 429 Too Many Requests error when the limit is exceeded. Include information about how long to wait before retrying.
    • Example (using a simple in-memory counter):
      # Pseudo code
      if client_requests[client_id] > MAX_REQUESTS_PER_HOUR:
        return 429, "Too Many Requests"
      else:
        client_requests[client_id] += 1

4. Error Handling

Provide informative and helpful error messages to clients without revealing sensitive information.

  1. Generic Error Messages: Avoid exposing internal details about your system.
  2. HTTP Status Codes: Use appropriate status codes (e.g., 400 Bad Request, 401 Unauthorized, 500 Internal Server Error).
  3. Logging: Log errors on the server-side for debugging and monitoring purposes.

5. Secure Storage

Protect sensitive data like API keys and user credentials.

  1. Encryption: Encrypt all sensitive data at rest and in transit (using HTTPS/TLS).
  2. Environment Variables: Store API keys in environment variables, not directly in your code.
  3. Database Security: Use strong passwords, restrict database access, and regularly back up your data.

6. Monitoring & Logging

Keep an eye on your API's performance and security.

  1. Log all requests: Include timestamps, client IP addresses, endpoints accessed, and request/response details (without sensitive data).
  2. Monitor for unusual activity: Look for spikes in traffic, failed authentication attempts, or unexpected errors.
  3. Alerting: Set up alerts to notify you of potential security issues.
Related posts
Cyber Security

Zip Codes & PII: Are They Personal Data?

Cyber Security

Zero-Day Vulnerabilities: User Defence Guide

Cyber Security

Zero Knowledge Voting with Trusted Server

Cyber Security

ZeroNet: 51% Attack Risks & Mitigation