In an API first approach, your software applications expose and consume their data through (REST) APIs. Those applications do not use legacy & fixed connections to external systems anymore. Instead, they embrace loosely coupling with a primary goal to run in a “hostile environment” such as the public cloud. Since the attack surface of an exposed API-driven application is much larger compared to a “traditional N-tier application”, you need to make sure your APIs are secured thoroughly. There is no infrastructure team to arrange security for you, developers need to carefully design and secure their APIs of which they are responsible. In this article, we will provide practical guidelines to secure your APIs.
APIs expose services and data to the outside world. Modern software development techniques such as serverless make this possible without the use of infrastructure components such as containers or Virtual Machines you need to maintain yourself. Without those infrastructure components to build a security design that implements the “defense in depth” principle, your APIs are much more vulnerable to the outside world. You need to rethink the principle of “Defense in Depth”.
Risk- and vulnerability management is all about reducing business risks and ensuring business continuity. The business risks of not securing an API are overwhelming:
- An attacker can steal, modify or delete precious data.
- A bad actor can access your (cloud) resources, making other services more vulnerable or exploitable as well.
- Your service can stop functioning if it faces a DDoS attack. If you do not know how to protect your API from that, your business is at serious risk.
- Critical information can leak to competitors: your valuable proposition vanishes.
Main security principles
Popular design principles to secure your APIs are:
- Strong authentication and authorization mechanisms.
- Apply the least privilege principle to limit the blast radius in case something goes wrong.
- Educate everyone who is involved in the design, development and operation of API-based applications. Security first should be the default mindset to everyone – including managers and budget holders.
Above mentioned risks and principles justify why your organization requires to spend the right time and effort to make sure your APIs are secure (by default). In a DevSecOps environment, teams work on API security-related aspects from the start of their software development activities until their applications are in production. Even beyond that if you take into account monitoring and logging of runtime systems.
API security vulnerabilities
Vulnerabilities in software source code are virtually everywhere. In the business logic itself, in IaC templates and in deployment scripts. API security vulnerabilities concentrate on the following attacks: application & data attacks, DDoS attacks, Login attacks and Parameter-based attacks.
Application and data attacks
Application and data attacks are big business risks for any organization. Using this kind of attack, a malicious person (whether it be an insider or outsider) misuses credentials, accounts, tokens, API keys or other pieces of information to gain access to critical systems. Often these secrets are gathered using social engineering techniques or luring people into a fake environment in which they enter their secret data.
Common attacks include phishing attacks in which users (accidentally) give away their secrets. Man-in-the-middle attacks happen when a bad actor intercepts confidential data between an insecure API and the regular user. Most often, this happens without the end-user noticing.
Your API must be protected from traffic floods (DDoS attacks). It needs to filter out and block useless requests which have the intention to make your API and thus your service becomes unresponsive. If you do not block those large amounts of useless requests, they can still put high pressure on your cloud bill. This can happen when your API handles “regular traffic” correctly and when an attacker stays below the set traffic limits. However, the financial damage can really shock you at the end of the month.
Hackers can use brute force attacks to probe APIs and see if they can gain access to it. Besides this, they can also use a so-called dictionary attack to find and misuse weak username/password combinations. With this in mind, they can use legitimate login credentials to access your API and find more vulnerabilities while they are in. If they gain access to a privileged account, they can also disrupt other users’ sessions and even block them. This would cause much harm to your other users and your reputational damage is a major problem.
Always validate any input which reaches your API. Validate query string parameters, query parameters, HTTP headers and URLs. Besides these, pay special care to the body of your REST API messages. Validate input for the correct format (e.g. numbers, strings, etc), the right pattern (such as a postal code), length of the input, etc. Use strong input validation techniques on the client as well as on the server-side to make sure user input (through the API) is actually validated. Be very conservative when it comes to file uploads. This is a really dangerous scenario.
There are several best practices to secure your APIs.
Exposure and monitoring
First of all, you need to know which APIs exactly you have deployed. Large enterprises often do not have a clear view of this. You can’t protect what you can’t see. Furthermore, laws and regulations often require certain security protections for your exposed data. Therefore it’s critically important to have a good overview of your APIs.
Once you do have them all listed, you need to make sure you keep an eye on what happens with them. You need to detect suspicious requests (e.g. a high number of failed requests which trigger error messages or traffic from invalid sources). The last argument is especially tricky if you opened up your API for the entire internet. What helps here is to capture anomalies that derivative from “expected” behavior.
Use quotas and rate-limiting to control the amount of traffic that accesses your APIs. Quotas help to put a limit on how much data can be sent and/or retrieved from your API whereas rate limits help to stop serving requests when a certain limit is met. Both protective measures help to keep your API responsive to everyone when (potential) bad actors are filtered out.
Authentication and authorization
Strong authentication and authorization methods help to define who can access your APIs and what that person or system can do once it has access.
Use Role-Based Access Control to determine which role a person or system has and carefully pinpoint what he/she can access using that role. This prevents a person who has a read-only or audit-based role to access an API that is meant for administrative purposes.
API security maturity levels
Generally speaking, there are four maturity levels of API security that are pretty common now:
- Level 0: API Keys and Basic Authentication: Use API keys in the body or URL of requests to verify them. No support for authorization here. API Keys are often compromised so they only offer basic protection.
- Level 1: Token-based Authentication: Use a Token-based architecture and include the user identity in the API requests. This acts as an extra step to differentiate internal and external users/systems. Authorization is still not covered and must be implemented using custom code. When the implementation of this custom code goes wrong, your system is at risk.
- Level 2: Token-based Authorization: This level adopts OAuth 2.0 to define Authorization and scopes. This further enhances security efforts since it brings tighter control to who can do what on the API. One of the downsides is that it brings more complexity.
- Level 3: Centralized Trust Using Claims: Use signed JSON Web Tokens where possible and control trust from a centralized location. Both actors help to solve the above-mentioned problems with levels 0 through 2. Level 3 is all about assertions that help to identify the identity of the request of the API. An identity is made out of multiple attributes which are to be trusted or not.
If you want to know more about the API Security Maturity Model, check out the website of Curity.io.
Be careful of your weakest link
Your weakest link is not always your API itself. Pay special attention to the way you expose it to the outside world. Consider the API gateway from AWS and a static website which accesses the API as an example.
Just like many other API Gateways, the AWS API Gateway is designed to expose APIs and control traffic that has the APIs as their destination. Many organizations deploy a single API Gateway for all of their APIs. It becomes an attractive target for hackers.
- An AWS API Gateway uses an IAM (Identity Access Management) role to access the underlying service (such as Lambda). If this IAM role does not utilize the least privilege principle, it can access much more resources with much more permissions than necessary.
- Enable API keys for your REST APIs. By default, a key is not required. Deploy an AWS WAF (Web Application Firewall) in front of the API Gateway. Block access which attempts to access the AWS API Gateway directly without passing through the WAF.
- Enable API key rotation in your CloudFormation stack when you deploy your Cloud infrastructure resources. You can do this by adding an API key rotation schedule parameter and choose an appropriate value. Don’t forget to set a default value, for example daily.
Before you deploy and expose your APIs, pay special care of the security part of it. Since APIs expose their data directly to the internet, you need to implement different security measures to effectively protect your valuable (data) assets. Traditional ways to secure them like an N-tier application are not enough or completely absent for your architecture. In this article we saw many examples and best practices to do that which help you get started.