Checklist for securing APIs
This document contains guidelines that will help you create and consume APIs in a secure way. This document is a general document, and you should always consider any other safety issues related to your specific domain and technology. This document supplements the security profile, which you should always adhere to.
The guidelines below are inspired by the document "OWASP cheat for REST Security" which you can find at this site.
General guidelines for securing REST based APIs
ℹ️ Secure all endpoints using HTTPS
Among other things, this will protect Access Tokens that are transferred between HelseID and the API-klient, as well as between API-clients and API endpoints.
ℹ️ Perform access control on every endpoint
Even if the API is hidden behind an API Gateway.
ℹ️ Require JWTs as security tokens
ℹ️ Restrict which HTTP methods that are used
Reject every HTTP methods that is not in use by responding with the HTTP status code 405 - "method not allowed"
ℹ️ Validate every input parameter
- Never trust input parameters, take a look at the OWASP Input Validation cheat sheet for detailed explanations
- Validate the lenght of the input-value, valid ranges and values, format and type
- All input parameters should be strongly typed
- Do not accept unexpected or unknown content
- Use libraries or frameworks for validating and sanitizing input values
- Define limits for data size in requests and reject requests that are too big by responding with the HTTP status code 413 - "Request Entity Too Large"
- Log errors that occur during input validation, consider implementing rules that temporarily ban API-clients that often fail.
ℹ️ Validate "content types"
If you don’t validate "content type" you open up for injecting and execution of code
Validate "content types" for incoming requests to your API
- Reject requests that lack "content type", or contain unexpected "content type" values.
- Respond to such requests with HTTP status codes:
- 406 - "Unacceptable"
- 415 - "Unsupported Media Type"
- Avoid exposing content types not in use by defining explicit content types; by doing this you can avoid XXE (XML External Entity) attacks.
Use safe content types in responses
- Don't copy the "Accept" header to the "Content-type" header of the response
- Do not accept the request if the "Accept" header contains type that is not allowed.
- Reply with HTTP status code 406 - "Not Acceptable" if the type stated in the "Accept" header is not allowed.
- Make sure "content type" headers in your responses matches content in body. Example: application/json and not application/javascript
ℹ️ Security headers
- Send "Content-Type" headeren with correct content type and charset.
- Send securityheader "X-Content-Type-Options: nosniff" to make sure that browser does not try to change Content-Type to something else than what was sent (Could lead to XSS).
- Send security header "X-Frame-Options: deny" to protect yourself from drag’n’drop clickjacking in older browsers.
ℹ️ Correct use of CORS
By delivering appropriate CORS headers, your REST API signals which domains (origins) are allowed to make JavaScript calls to the REST service.
- Disable CORS headers if cross-domain calls are not supported or expected.
- Be as specific as possible and as general as necessary when defining which origins are valid for cross-domain calls.
ℹ️ Make sure your APIs always sends correct HTTP response codes
⚠️ Avoid the exposure of enpoints for administration on the internet
⚠️ Be careful when handling errors
- Reply with generic error messages - avoid exposing details about the error if its not neccessary
- Do not give away technical details such as "call stacks" or internal information to the API-client