The web has moved past standard HTTP. With browser vendors flagging URLs that don’t use a secure layer, it’s time to do the same for your API. HTTPS uses Transport Layer Security (TLS) to encrypt traffic. This means communication between the client and server is encrypted. For your API, this means the content sent from your API is secured from third parties, and it means that the access credentials are secured.
Speaking of access credentials, the way to avoid unexpected use of your API is to ensure proper authentication. Authentication is how you allow or prevent access to the API. Even publicly available APIs that are free to use should consider an authentication strategy. This gives you to limit or remove users that abuse the API, and also protect your users by giving them the ability to reset their credentials if needed.
Authentication’s sibling is an authorization. Where authentication is concerned with whom the user of your API is, Authorization focuses on what they have access to. For example, free plan users may only be authorized to access a subset of your full API. When you think about integrations like social login, the user authorize your application to read their profile data from the social platform.
Secure endpoints and resources (Object level authorization)
It’s common to secure an endpoint or set of endpoints through authorization. A more future-proof approach is to secure the individual resources as well. This prevents misconfigured, endpoint-level authorization from reaching your data. It also means that the endpoints themselves aren’t restricted by user type, but instead the resource controls who can and cannot view it.
When we think of security, we often think of inappropriate access. It can also be useful to think of security as managing resources. Rate-limiting is a technique for throttling the usage of an API. It can protect your resources financially but also ensure that your servers aren’t overloaded by a flood of requests at one time. Many rate-limiting approaches are time-based. They can be set for a billing period to handle overall usage, as well as use a “burst” approach to limit large influxes of requests. If you’ve ever seen the 429 HTTP status code, you’ve experienced rate-limiting.
Validate and sanitize input
One of the oldest attack points for web applications is input fields. The way we access data may have changed, but the need to validate any user input hasn’t. Client-side validation helps prevent mistakes and improve the user experience, your API also needs to validate and sanitize all input before acting on it. Sanitization strips malicious or invalid code from requests. Validation ensures that the data meets the necessary criteria that your resources expect. This could be type and shape, or even factors like password structure.
Expose what is needed
It can be tempting to take a shortcut and directly map data models to endpoints. Not only can this provide overly-verbose responses and increase bandwidth usage, but it can also expose data that users don’t need access to. For example, consider a /user endpoint that returns the user’s profile. It may require some information about the user, but it doesn’t need the user’s password or access levels.
Arrange blunder messages
Notwithstanding disinfecting information that goes into your API, you’ll need to clean the data that emerges from it. Blunder messages assume a critical part in helping clients comprehend that an issue happened, yet try not to release any touchy information. Furnishing end-clients with insights regarding the structure of your inside code can open up territories for assailants to zero in on. Try to arrange blunder messages to give enough data to assist clients with troubleshooting and enough for them to report issues, yet insufficient to uncover the internal operations of your application or delicate information.
Don’t expose sensitive information
To build on protecting sensitive data, make sure not to expose details in JSON web tokens (JWTs) or cookies. The body of a JWT have the illusion of being secure, but can easily be decoded. Because of this, you should avoid including user information that could be used to access your application. The same advice goes for URLs as well. Make sure query strings aren’t exposing sensitive details.
Assess your dependencies
We no longer develop in a silo. A good portion of every codebase now contains libraries, middleware, and a variety of dependencies from outside sources. While it is generally safe to assume that popular packages are “battle-tested”, that doesn’t mean they aren’t completely safe from vulnerabilities. Make sure to assess your dependencies. Are they well maintained? Are you using the latest version? Is there a history of problems? Perhaps more importantly: Do you really need a library for what you’re doing?
Allow users to track and reset authentication keys
One additional way to improve the security of your API is to allow users to reset their credentials and monitor their usage. A common mistake is not allowing users to reset their API keys. If a consumer of your API exposes their key accidentally, or it is taken maliciously, the problem now directly affects your API. Instead, create a means for them to manage access.
Standardize auth across your services
We’ve seen the big players in API like Google, Microsoft, and Amazon standardize the authorization and authentication process for their APIs. Consider a centralized means of doing this, like using an API gateway or a dedicated point of entry for handling authentication requests.
Follow standard guidelines from OWASP
In addition to these best practices, consider adopting recommendations from The Open Web Application Security Project (OWASP). They offer platform-specific guides as well as an upcoming API-specific guide, The API Security Top 10. Beyond securing your API on a code-level, you’ll also want to ensure that your servers and infrastructure are configured properly to avoid unauthorized access.