StackHawk
Hamburger Icon

Understanding and Protecting
Against OWASP API10: Unsafe
Consumption of APIs

stackhawk

StackHawk|February 29, 2024

Learn about OWASP API10 and the risks associated with examples and best practices to prevent unsafe API consumption.

In our increasingly interconnected world, APIs (Application Programming Interfaces) form the backbone of modern digital systems. They power seamless data exchange and enable applications to communicate effortlessly. Because of their rise in usage and popularity, they’ve also become a target for bad actors to exploit. This has led to the OWASP Top 10 API Security Risks, a list developed by OWASP to highlight the top API vulnerabilities that could be and are exploited in the wild. One of the vulnerabilities highlighted in the 2023 edition of the list, in tenth position, is API10: Unsafe Consumption of APIs.

Secure APIs image

With so many APIs available from third-party providers, our reliance on external APIs can introduce hidden dangers. The OWASP API10: Unsafe Consumption of APIs vulnerability highlights how interactions with untrusted, compromised, or poorly designed third-party APIs can significantly jeopardize your application's security. In this blog, we'll delve into this vulnerability and help you fortify your API endpoints against such an attack.

Understanding OWASP API10: Unsafe Consumption of APIs

At its core, the OWASP API10 vulnerability arises when developers integrate their applications with other APIs without thoroughly assessing those external dependencies' trustworthiness and security posture. Since third-party APIs might adopt weaker security standards, it can make them susceptible to certain vulnerabilities. Scenarios that could lead to the "unsafe consumption of APIs" vulnerability include:

  • Dependency on Vulnerable APIs: If an external API your application relies on has known vulnerabilities, attackers could exploit those weaknesses to gain unauthorized access to your application's sensitive data or functionality.

  • Lack of Validation: Not adequately validating data received from third-party APIs could lead to injections (like SQL injections or command injections), allowing attackers to manipulate your application's behavior.

  • Over-Reliance on APIs: If you expose too much of your own application's critical functionality through APIs, other systems making calls to those APIs could inadvertently open up security risks.

The Impact: What's at Stake?

Magnifying glass on code image

Unsafe consumption of APIs can have far-reaching consequences, compromising the security and integrity of your application. Here's a look at some potential impacts:

  • Data Breaches: Attackers could exploit vulnerabilities in integrated APIs to access, manipulate, or steal confidential user data stored in your application.

  • System Takeover: Attackers might leverage API weaknesses to hijack your application's functionalities or gain complete control over your systems.

  • Denial of Service (DoS): Malicious actors could flood vulnerable APIs with requests, overwhelming your application and rendering it unavailable to legitimate users.

  • Reputational Damage: A security breach stemming from this vulnerability can seriously erode trust in your application, leading to loss of customers and revenue.

Unsafe consumption of APIs tends to stack on top of other known vulnerabilities, such as SQL and script injection. If the third-party applications are vulnerable to these types of attacks then, without the proper mechanisms in place, your application also becomes susceptible too.

A Real-World Example of Unsafe API Consumption

Let's illustrate the OWASP API10 vulnerability with a Python (Flask) example. Consider a simple API endpoint that uses a third-party weather API. Below is some code that exposes a /weather/{city} endpoint that retrieves the weather data for a specific city passed to the endpoint. The data passed through the {city} parameter is then used to call the third-party weather API.

from flask import Flask, jsonify
import requests
app = Flask(__name__)
@app.route('/weather/<city>')
def get_weather(city):
    weather_api_key = "YOUR_WEATHER_API_KEY" 
    weather_api_url = f"https://api.someweathercompany.com/current?access_key={weather_api_key}&query={city}"
    response = requests.get(weather_api_url)
    return response.json()
if name == '__main__':
    app.run(debug=True)

If the third-party someweathercompany.com API is compromised or suffers from an injection vulnerability, a malicious user could provide a specially crafted input to the {city} parameter. Since the data sent to the API is not sanitized or checked, this parameter could expose sensitive data from your application or allow the attacker to execute arbitrary code on your backend system.

To understand attacks, let's explore some potential malicious scenarios that target the vulnerable weather API example above.

Scenario #1: Indirect SQL Injection

Imagine our weather app allows users to save their favorite locations and offers localized weather forecasts. To obtain precise coordinates, it relies on a third-party geocoding API. However, the geocoding API has a vulnerability that attackers can exploit to inject malicious code into location names. A clever attacker might submit a location like:

New York'; DELETE FROM saved_locations --

If our application blindly stores this data in its database and later builds dynamic SQL queries using it, the injected payload could delete a user's saved locations or cause even more extensive damage.

Scenario #2: Manipulated Redirects

Let's say our application wants to partner with a third-party API to provide historical weather data for a given location and date. If this weather history API becomes compromised, attackers could manipulate it to send redirects for API calls, like so:

Original Request to Weather History API:

https://weatherhistoryapi.com/data?location=London&date=2023-02-27

Malicious Redirect Response (HTTP 308):

Location: https://attacker.com/collect_data 

An application that doesn't carefully handle redirects might blindly resend the request, including sensitive location and date details, to the attacker-controlled server.

Scenario #3: Tricky Filenames

Although possible but less likely, let’s imagine our weather app has a niche feature allowing users to upload their weather observations. These files are stored, and their filenames are kept in a database. An attacker could upload a file named:

weather_data_2023.csv'; DROP TABLE user_data; -- 

If our app isn't rigorously sanitizing filenames before using them in database interactions, this payload could lead to losing important user data.

Although these are just a few possible scenarios, they highlight how vulnerabilities in external systems we depend on can cascade into problems for our applications. Of course, for these particular exploits, our /weather/{city} can implement some logic to prevent such attacks from being effective. Let’s look at how that can be done in the next section.

Prevention: Best Practices to Secure API Consumption

Vigilance is crucial when working with external APIs. As API interactions happen, developers should ensure that user input is properly handled and that any interaction with any integrated third-party services is limited to only what is required for your app. Making sure that your API that leverages the third-party API is secure requires quite a few important factors. Let’s look at a short list of what to look out for and what to do.

  1. Inventory and Assessment:

    • Maintain a comprehensive list of every third-party API you interact with.

    • Thoroughly research their security track record. Look for documented vulnerabilities, patch processes, and their overall security posture.

  2. Input Sanitization and Validation (Always!)

    • Never trust data from external APIs. Apply rigorous input validation to everything you receive.

    • Whitelist Allowed Characters: Create a strict list of permitted characters for inputs like location names. Reject everything else.

    • Parameterize Queries: When interacting with databases, use parameterized queries to separate user-supplied data (even data coming through third-party APIs ) from your query logic, eliminating a major vector for injection attacks.

  3. Principle of Least Privilege:

    • Expose only the absolute minimum API functionality required. Avoid giving third-party systems wide access to your data or actions.

  4. Secure Communication:

    • Always use HTTPS for communication with APIs to protect data in transit.

  5. Error Handling with Care:

    • Avoid returning verbose error messages from upstream APIs. Return generic, non-informative messages to limit potential information leaks for attackers to exploit.

  6. Continuous Monitoring

    • Monitor external APIs for new vulnerabilities, security advisories, and updates. Regularly review your API usage patterns for anomalies.

Fixing Our Weather API Code

With this in mind, let’s apply some of these tips to our existing weather API. Below is a new and improved version of the API that includes some of the measures we covered above.

from flask import Flask, jsonify
import re 
import requests
app = Flask(__name__)
@app.route('/weather/<city>')
def get_weather(city):
    weather_api_key = "YOUR_WEATHER_API_KEY" 
    weather_api_url = f"https://api.someweathercompany.com/current?access_key={weather_api_key}&query={city}"
    # Input Sanitization
    if not re.match(r"^[A-Za-z0-9 ]+$", city):
       return jsonify({"error": "Invalid city name"})
    # API call logic
    response = requests.get(weather_api_url)
    # Assumes the weather API returns appropriate JSON data 
    return response.json()
if name == '__main__':
    app.run(debug=True)

As we saw, the original version of the target API, the /weather/{city} endpoint, didn't have any measures to prevent malicious input from being sent to the weather API. This made it susceptible to various attacks like SQL injection or command injection. The code above adds additional logic for input sanitization and error handling. Here are the specifics we’ve added:

  1. Input Sanitization: We've introduced a regular expression (re.match(r"^[A-Za-z0-9 ]+$", city)) to ensure the city parameter from the user consists only of letters, numbers, and spaces. This whitelist approach significantly reduces the surface area for attacks by rejecting unexpected characters.

  2. Error Handling: A simple error message ("Invalid city name") is returned if the input validation fails. This gives the user feedback without revealing sensitive or verbose implementation details that an attacker might misuse.

These changes implement the core security principle of "never trust user input." By sanitizing the data before it's sent to the external weather API, we've added a crucial layer of defense against potential injection attacks. This protects both your server from direct compromise and prevents your application from being used as a tool to attack the weather API itself.

Beyond the Basics

Coworkers around a computer screen image

Beyond adding some additional logic to the code directly, we can also add additional measures using other tools. These include adding rate limiting and monitoring mechanisms for the API endpoint.

For rate limiting, you’ll want to implement it on your side as an additional layer of protection, even if the weather API has its own limits in place. This can easily be done by using an API gateway or API management solution.

To monitor your APIs, you can set up logging and monitoring for API interactions (both requests you send and responses you receive) to detect unusual activity or unexpected errors. Various API monitoring and analytics solutions can alert you when specific criteria, such as potentially malicious usage, occur.

StackHawk: Your API Security Ally

Manually identifying and fixing API vulnerabilities can be time-consuming and prone to oversights. StackHawk offers a powerful solution to streamline the improvement of your API security posture against the threats outlined in the OWASP API Top 10. Developers who use StackHawk can leverage:

  • Automated Scanning: StackHawk probes your running APIs in pre-production and production environments, uncovering vulnerabilities that static code analysis might miss.

  • OWASP Alignment: StackHawk's testing targets explicitly a wide range of vulnerabilities from the OWASP API Top 10, including issues like BOLA, injection flaws, and inadequate resource consumption protections.

  • Actionable Guidance: Beyond just identifying problems, StackHawk offers clear remediation instructions and contextual information, empowering developers to resolve vulnerabilities quickly.

  • Integrates into Your Workflow: StackHawk seamlessly plugs into your existing CI/CD pipelines, enabling continuous security assessment as a part of your development process.

With StackHawk, you can proactively discover vulnerabilities before they hit production, prioritize fixes, and empower developers to “shift left”. Sign up today to try out StackHawk for yourself and begin tackling the OWASP Top 10 API Security Risks with ease and automation!


StackHawk  |  February 29, 2024

Read More

API Security Testing Overview and Tooling Guide

API Security TestingTools Overview & Guide

Applying the OWASP API Security Top 10 to GraphQL APIs

Applying the OWASPAPI Security Top 10to GraphQL APIs

Understanding The 2023 OWASP Top 10 API Security Risks

Understanding The 2023 OWASP Top 10 APISecurity Risks