When designing a REST API or service are there any established best practices for dealing with security (Authentication, Authorization, Identity Management) ?
When building a SOAP API you have WS-Security as a guide and much literature exists on the topic. I have found less information about securing REST endpoints.
While I understand REST intentionally does not have specifications analogous to WS-* I am hoping best practices or recommended patterns have emerged.
Any discussion or links to relevant documents would be very much appreciated.
If it matters, we would be using WCF with POX/JSON serialized messages for our REST API’s/Services built using v3.5 of the .NET Framework.
18 s
There is a great checklist found on Github:
Authentication
-
Don’t reinvent the wheel in Authentication, token generation, password storage. Use the standards.
-
Use
Max Retry
and jail features in Login. -
Use encryption on all sensitive data.
JWT (JSON Web Token)
-
Use a random complicated key (JWT Secret) to make brute forcing the token very hard.
-
Don’t extract the algorithm from the payload. Force the algorithm in the backend (HS256 or RS256).
-
Make token expiration (
TTL
,RTTL
) as short as possible. -
Don’t store sensitive data in the
JWT
payload, it can be decoded easily.
OAuth
-
Always validate
redirect_uri
server-side to allow only whitelisted URLs. -
Always try to exchange for code and not tokens (don’t allow
response_type=token
). -
Use state parameter with a random hash to prevent
CSRF
on theOAuth
authentication process. -
Define the default scope, and validate scope parameters for each application.
Access
-
Limit requests (Throttling) to avoid DDoS / brute-force attacks.
-
Use HTTPS on server side to avoid MITM (Man In The Middle Attack)
-
Use
HSTS
header with SSL to avoid SSL Strip attack.
Input
-
Use the proper HTTP method according to the operation:
GET
(read),POST
(create),PUT/PATCH
(replace/update), andDELETE
(to delete a record), and respond with405 Method Not Allowed
if the requested method isn’t appropriate for the requested resource. -
Validate content-type on request
Accept
header (Content Negotiation) to allow only your supported format (e.g.application/xml
,application/json
, etc) and respond with406 Not Acceptable
response if not matched. -
Validate
content-type
of posted data as you accept (e.g.application/x-www-form-urlencoded
,multipart/form-data
,application/json
, etc). -
Validate User input to avoid common vulnerabilities (e.g. XSS, SQL-Injection, Remote Code Execution, etc).
-
Don’t use any sensitive data (credentials, Passwords, security tokens, or API keys) in the URL, but use standard
Authorization
header. -
Use an API Gateway service to enable caching,
Rate Limit
policies (e.g. Quota, Spike Arrest, Concurrent Rate Limit) and deploy APIs resources dynamically.
Processing
-
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.
-
Don’t auto-increment IDs. Use UUID instead.
-
If you are parsing XML files, make sure entity parsing is not enabled to avoid XXE (XML external entity attack).
-
If you are parsing XML files, make sure entity expansion is not enabled to avoid Billion Laughs/XML bomb via exponential entity expansion attack.
-
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.
Output
-
Send
X-Content-Type-Options: nosniff
header. -
Send
X-Frame-Options: deny
header. -
Send
Content-Security-Policy: default-src 'none'
header. -
Remove fingerprinting headers –
X-Powered-By
,Server
,X-AspNet-Version
etc. -
Force
content-type
for your response, if you returnapplication/json
then your response content-type isapplication/json
. -
Don’t return sensitive data like credentials, Passwords, security tokens.
-
Return the proper status code according to the operation completed. (e.g.
200 OK
,400 Bad Request
,401 Unauthorized
,405 Method Not Allowed
, etc).