Checklist of the most important security countermeasures when designing, testing, and releasing your API.
Don't use Basic Auth. Use standard authentication instead (e.g., JWT).
Basic Auth
Don't reinvent the wheel in Authentication, token generation, password storage. Use the standards.
Authentication
token generation
password storage
Use Max Retry and jail features in Login.
Max Retry
Use encryption on all sensitive data.
Use a random complicated key (JWT Secret) to make brute forcing the token very hard.
JWT Secret
Don't extract the algorithm from the header. Force the algorithm in the backend (HS256 or RS256).
HS256
RS256
Make token expiration (TTL, RTTL) as short as possible.
TTL
RTTL
Don't store sensitive data in the JWT payload, it can be decoded easily.
Avoid storing too much data. JWT is usually shared in headers and they have a size limit.
Limit requests (Throttling) to avoid DDoS / brute-force attacks.
Use HTTPS on server side with TLS 1.2+ and secure ciphers to avoid MITM (Man in the Middle Attack).
Use HSTS header with SSL to avoid SSL Strip attacks.
HSTS
Turn off directory listings.
For private APIs, allow access only from safelisted IPs/hosts.
Always validate redirect_uri server-side to allow only safelisted URLs.
redirect_uri
Always try to exchange for code and not tokens (don't allow response_type=token).
response_type=token
Use state parameter with a random hash to prevent CSRF on the OAuth authorization process.
state
Define the default scope, and validate scope parameters for each application.
Use the proper HTTP method according to the operation: GET (read), POST (create), PUT/PATCH (replace/update), and DELETE (to delete a record), and respond with 405 Method Not Allowed if the requested method isn't appropriate for the requested resource.
GET (read)
POST (create)
PUT/PATCH (replace/update)
DELETE (to delete a record)
405 Method Not Allowed
Validate content-type on request Accept header (Content Negotiation) to allow only your supported format (e.g., application/xml, application/json, etc.) and respond with 406 Not Acceptable response if not matched.
content-type
application/xml
application/json
406 Not Acceptable
Validate content-type of posted data as you accept (e.g., application/x-www-form-urlencoded, multipart/form-data, application/json, etc.).
application/x-www-form-urlencoded
multipart/form-data
Validate user input to avoid common vulnerabilities (e.g., XSS, SQL-Injection, Remote Code Execution, etc.).
XSS
SQL-Injection
Remote Code Execution
Don't use any sensitive data (credentials, Passwords, security tokens, or API keys) in the URL, but use standard Authorization header.
credentials
Passwords
security tokens
API keys
Use only server-side encryption.
Use an API Gateway service to enable caching, Rate Limit policies (e.g., Quota, Spike Arrest, or Concurrent Rate Limit) and deploy APIs resources dynamically.
Quota
Spike Arrest
Concurrent Rate Limit
Check if all the endpoints are protected behind authentication to avoid broken authentication process.
User own resource ID should be avoided. Use /me/orders instead of /user/654321/orders.
/me/orders
/user/654321/orders
Don't auto-increment IDs. Use UUID instead.
UUID
If you are parsing XML data, make sure entity parsing is not enabled to avoid XXE (XML external entity attack).
XXE
If you are parsing XML, YAML or any other language with anchors and refs, make sure entity expansion is not enabled to avoid Billion Laughs/XML bomb via exponential entity expansion attack.
Billion Laughs/XML bomb
Use a CDN for file uploads.
If you are dealing with huge amount of data, use Workers and Queues to process as much as possible in background and return response fast to avoid HTTP Blocking.
Do not forget to turn the DEBUG mode OFF.
Use non-executable stacks when available.
Send X-Content-Type-Options: nosniff header.
X-Content-Type-Options: nosniff
Send X-Frame-Options: deny header.
X-Frame-Options: deny
Send Content-Security-Policy: default-src 'none' header.
Content-Security-Policy: default-src 'none'
Remove fingerprinting headers - X-Powered-By, Server, X-AspNet-Version, etc.
X-Powered-By
Server
X-AspNet-Version
Force content-type for your response. If you return application/json, then your content-type response is application/json.
Don't return sensitive data like credentials, passwords, or security tokens.
passwords
Return the proper status code according to the operation completed. (e.g., 200 OK, 400 Bad Request, 401 Unauthorized, 405 Method Not Allowed, etc.).
200 OK
400 Bad Request
401 Unauthorized
Audit your design and implementation with unit/integration tests coverage.
Use a code review process and disregard self-approval.
Ensure that all components of your services are statically scanned by AV software before pushing to production, including vendor libraries and other dependencies.
Continuously run security tests (static/dynamic analysis) on your code.
Check your dependencies (both software and OS) for known vulnerabilities.
Design a rollback solution for deployments.
Use centralized logins for all services and components.
Use agents to monitor all traffic, errors, requests, and responses.
Use alerts for SMS, Slack, Email, Telegram, Kibana, Cloudwatch, etc.
Ensure that you aren't logging any sensitive data like credit cards, passwords, PINs, etc.
Use an IDS and/or IPS system to monitor your API requests and instances.
Last updated 1 year ago