How to fix the top 5 API vulnerabilities
APIs are more ubiquitous than ever, but many are still subject to well-known and often easily preventable vulnerabilities.
APIs are critical to the success of an application, but these little bits of code are an extremely popular attack vector.
APIs enable applications and users to easily access and interact with an organization's digital data and services. They are so popular that they account for about 83% of global internet traffic. Yet, APIs also provide open entry points into well-guarded IT infrastructure. Without proper protection, malicious actors can easily gain a foothold into a network via an API. In fact, 20% of survey respondents said they suffered a data breach in the past year due to API security gaps.
Security teams must concentrate on eliminating the following five vulnerabilities, which -- despite being well known -- are still often present and exploitable in today's APIs.
1. Weak authentication
Authentication verifies a user or device is who they claim to be. This prevents people or devices without the correct permissions from accessing information and resources. If the authentication process is easy to circumvent or compromise -- such as weak or easily guessed passwords -- an attacker can masquerade as a legitimate user on a one-time or permanent basis.
Enforce strong password use and multifactor authentication for access to sensitive resources, such as bank accounts, to reduce the possibility of account takeover. More importantly, ensure password and authentication processes work as expected. This requires extensive testing, particularly of how session cookies are managed because they can easily introduce exploitable weaknesses. Session cookies should be completely random and unpredictable and refresh after each successful login or change in the level of access. Any attempts to access resources without being correctly authenticated should receive the "401 Unauthorized" response status code. Limit the number of unsuccessful login attempts, after which the account is locked. Use API keys to identify users but not to authenticate or authorize them, as keys are too easily exposed and misused.
2. Missing object authorization
Often referred to as broken object-level authorization, this occurs when server-side checks don't confirm the requester is authorized to access or modify the data and objects listed in the request. For example, an attacker could change the user ID in a request to see if information about a different user is returned, which could lead to unauthorized access to data. This flaw was notedly discovered in an Uber API in 2019 that enabled drivers to access other drivers' data simply by changing the user ID. If functions to modify data also lack properly implemented authorization checks, attackers maybe able to alter or delete data and even completely take over another user's account.
Identifiers for objects should be random and unpredictable rather than predictable sequential values that can be easily guessed. Server-side checks should also verify the following:
- The user is authorized to access the object requested.
- The user has the necessary permissions to execute a particular operation on the object.
3. Injection vulnerabilities
When an API receives user-supplied data but doesn't parse and validate it before processing the request, attackers can send malicious data or commands to trigger an injection attack. Database queries and OS commands can all be potentially executed via XML, JSON, cross-site scripting (XSS), SQL and NoSQL injections to gain access to data or execute malicious commands without authorization.
Rather than creating your own functions to validate and sanitize incoming data, take advantage of the many specialist libraries that implement allowlists to ensure data is the required type and length, and remove unexpected characters or parameters and known injection commands. Run these checks against every incoming request.
4. Excess data exposure
API responses to a request often return far more data than required to fulfill the request. This usually occurs because it is simpler for a developer to write code that returns an entire row from a table rather than only the specific field(s) required. For example, a profile page on a messaging app may display a person's name and age, but often, API requests return all the information stored about the user rather than just that user's name and age calculated from their date of birth. Although the app may filter the response and only display the name and age, it is simple for attackers to read and collect other details returned in the request, including personally identifiable information, such as date of birth, email address and location. This exposure of sensitive data may violate data access policy rules and compliance regulations.
API responses should only return the data necessary to fulfill a request; database queries made by the API should select just the relevant record(s) and field(s). An API's documentation should state what data is required to fulfill a request, so it should be an easy fix to ensure database queries match fields and records requested. Remember that the client app can only filter what data is visible to the user, not what data it receives.
5. Poorly configured security
APIs run on complex infrastructures, with resources scaled up and down automatically depending on demand. If security controls are not correctly configured at each layer, sensitive data and systems can be at risk. Common misconfigurations include unpatched devices and applications, insecure default configurations, data not being encrypted in transit, and open and insecure cloud storage and services.
APIs should only expose HTTPS endpoints. Because HTTPS endpoints are open to the internet, however, it's also essential that rate limiting is correctly applied to control the rate of requests and the number of resources requested. Otherwise, they are open to DoS and brute-force attacks. Disable unused HTTP methods, such as TRACE, and add the appropriate HTTP response security headers, such as X-Content-Type-Options: nosniff to prevent XSS and X-Frame-Options: deny to prevent clickjacking attempts. Also, any error messages that an API request generates should include only minimal information to ensure no sensitive data about the system is revealed, such as technical details of the error.
How to improve overall API security
The key to ensuring APIs don't open vulnerable channels into IT infrastructure is to focus on protecting the resources they access and the actions users can perform on them. This means instigating authentication and authorization checks not just once, but continuously with a zero-trust strategy.
Use threat modeling to shape the design of your APIs to incorporate security controls, such as strong identity control and access management features, at the beginning of the build phase to mitigate identified risks. Test that these controls work within the DevOps workflow.
Attackers can spend days conducting reconnaissance and exploration before they successfully exploit an API as part of a cyber attack. Organizations should deploy comprehensive logging and monitoring of API traffic to spot and stop attacks before they cause damage. Work from an up-to-date API inventory, and regularly review security controls and configurations to ensure they remain appropriate and effective.
Legacy perimeter-based security is not sufficient to block attacks in highly distributed API infrastructures. Scheduled security audits of containers, microservices, cloud storage and continuous integration/continuous delivery pipelines are vital to prevent unused or forgotten access points that are unprotected from exploitation.
Emphasizing security over speed during development can also be a big step forward in eliminating API security flaws that continue to put data and users at risk before they reach the production version.