APIs (Application Programming Interfaces) serve as the lifeline of modern software, connecting applications and services in an elegant yet light way. Because these APIs are playing an increasingly crucial role in today’s world, securing them becomes crucial.
An essential part of SDLC is API Penetration Testing, which ensures that any weak points within an organization’s API implementation are highlighted before attackers can reap its benefit (exploit them).
This blog post is to help you better understand API penetration testing, the types of vulnerabilities that may arise during automated or manual testing, and the best strategies for finding a vulnerability before harm occurs. So, without further ado, let’s get started.
What is API Penetration Testing?
API pentesting is defined as the process of verifying the security of an Application Programming Interface by imitating real hacker attacks (hacker-style attacks). Security professionals/engineers test an API for vulnerabilities, improper configurations, and design flaws to manipulate APIs in a harmful or unintended way.
The aim of security testing for APIs is to expose and remediate security risks before a hacker exploits the opportunity.
During an API pentest, security testers focus on:
- Identifying and discovering the API endpoints (this includes hidden endpoints).
- Examining authentication and authorization models used by APIs.
- Testing for injection vulnerabilities, such as SQL, NoSQL, and command injection.
- Verifying how data enters the application and how it is sanitized.
- Analyzing rate-limiting and resource use.
The significance of API pentest tools is impossible to ignore in today’s interconnected digital world, where the usage of APIs is on the rise. In many cases, APIs serve as entryways to sensitive information and services. As a result, API endpoints are prime targets for attackers. A penetration testing allows companies to:
- Detect and remediate security vulnerabilities on a frequent basic.
- Ensuring compliance with business standards and authorities.
- Protecting sensitive information from unauthorized exposure and manipulation.
- Preserve customers’ trust and business image.
API pentesting shares similarities with regular web application assessments. There are a few differences:
- API testing focuses more on the application’s backend services and data exchange activities than web app testing, including the frontend sections.
- APIs frequently use token or key-based authentication rather than web-based session authentication, therefore the testing strategy differs.
- The prevalence of structured data paradigms like JSON or XML in APIs necessitates certain parsing methods and use.
- API endpoints are frequently hidden or require advanced reconnaissance tools to discover.
- The nature of APIs makes it easier for automated testing to be performed.
Why Astra is the best in API Pentesting?
- We’re the only company that combines automated & manual pentest to create a one-of-a-kind pentest platform.
- Runs 120+ test cases based on industrial standards.
- Integrates with your CI/CD tools to help you establish DevSecOps.
- A dynamic vulnerability management dashboard to manage, monitor, and assess APIs your web app consumes.
- Conduct 2 rescans in 60 days to verify patches.
- Award publicly verifiable pentest certificates which you can share with your users.
- Helps you stay compliant with SOC2, ISO27001, PCI-DSS, HIPAA, etc.
- Trusted by the brands you trust like Agora, Spicejet, Muthoot, Dream11, etc.
Scope & Timeline of API Penetration Testing
A typical API penetration testing scope outlines the specific APIs to be tested, the API penetration testing methodology to be employed, the scope of vulnerabilities to be identified (e.g., authentication, authorization, data exposure), and the expected deliverables (e.g., vulnerability reports, remediation recommendations).
It can also include timelines for the deliverables, such as the average API manual pentest, which can take 5-10 business days. Both parties’ responsibilities are listed alongside mutually agreed-upon terms and conditions, such as liability, confidentiality, and intellectual property rights.
Cost for API Pentesting
The cost of an API penetration test is highly variable and influenced by factors such as the number of endpoints, APIs, and their complexity.
Since the average API has 5-7 endpoints, a general estimate of $1500 per API can serve as a starting point, but the actual price can fluctuate significantly based on the specific intricacies of the system under assessment.
3 Common Vulnerabilities Found in APIs
Modern applications run on APIs, but in doing so, they also face many new security risks. Here are three of the most common vulnerabilities in modern APIs.
Some of the most common web security attacks result in compromised authentication, leading to data and financial loss.
Broken Authentication and Authorization
APIs need proper authentication and authorization. If not, a critical target is broken wherein the system does not properly authenticate users or enforce access controls. This mostly happens due to an issue in handling authentication tokens (session or refresh tokens) or insufficient checks surrounding user permissions at the API endpoint level.
One common way to handle stateless authentication with APIs is using JSON Web Tokens (JWTs). This is a standard structure for JWT:
Authorization: Bearer <<JWT>>
The decoded payload (sample) contains the following claims:
{
"user_id": 123,
"role": "user"
}
APIs are still vulnerable to no cryptographic token signature verifications or not validating claims. Payload modification for privilege escalation can be beneficial for the attacker. Eg:
{
"user_id": 123,
"role": "admin"
}
Another vulnerability in APIs is Insecure Direct Object References (IDOR). Consider an API endpoint:
GET /api/v1/pingUsers/{id}/financialRecords
This might be exploited by an attacker if authorization checks are not performed at the server level and the attacker starts to iterate for different {id} values like:
GET /api/v1/clients/12345/documents
GET /api/v1/users/12347/financial-records
This could allow an unauthorized user to access other profiles with sensitive information and details.
In the below case (another example), improper handling of the redirect_uri
parameter in OAuth 2.0 implementations can result in open redirect vulnerabilities. For instance:
GET /oauth/authorize?client_id=123&redirect_uri=https://attacker.com
This happens when the developers don’t whitelist the redirect_uri so that anyone can redirect users to a malicious website.
Learn more about how JWTs work in depth.
Injection Vulnerabilities
API Injection flaws arise when untrusted data from a user is used in commands or queries without sanitation and validation, causing a form of injection.
These vulnerabilities could be exploited by attackers to change the behavior of the API and possibly abuse it to gain unauthorized access to data or even compromise the system.
SQL Injection
SQLi is an example of a critical vulnerability in modern APIs when developers forget to handle user input when querying a database properly. For example, below is an API endpoint for user authentication:
@app.route('/api/login', methods=['POST'])
def login():
username = request.json.get('username')
password = request.json.get('password')
query = f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}'"
result = db.execute(query).fetchone()
if result:
return jsonify({"status": "success", "user_id": result['id']})
else:
return jsonify({"status": "failure"}), 401
This implementation is vulnerable to SQL injection. An attacker could exploit it with a payload like:
{
"username": "admin'--",
"password": "anything"
}
The resulting SQL query becomes:
SELECT * FROM users WHERE username = 'admin'--' AND password = 'astra-security'
This effectively comments out the password check, allowing authentication as ‘admin’ without knowing the password.
NoSQL Injection
Even in cases of NoSQL databases, which are different by nature from SQL ones, you can make an injection attack, too. Ultimately, these vulnerabilities originate from the mishandling of user-entered input in query structures.
For example, you have a MongoDB-based API that has a login endpoint:
app.post('/api/login', async (req, res) => {
const { username, password } = req.body;
const user = await db.collection('users').findOne({ username, password });
if (user) {
res.json({ status: 'success', userId: user._id });
} else {
res.status(401).json({ status: 'failure' });
}
});
This implementation is vulnerable to NoSQL injection. An attacker could exploit it with a carefully crafted payload:
{
"username": {"$ne": null},
"password": {"$ne": null}
}
When this payload is processed, the MongoDB query becomes:
db.collection('users').findOne({
username: {$ne: null},
password: {$ne: null}
})
This query matches any document where both username and password are not null, potentially allowing authentication as the first user in the collection.
Learn more about $ne in MongoDB.
Command Injection
A Command Injection vulnerability occurs in APIs when user input is passed to system commands without any kind of sanitization. This may allow attackers to run arbitrary commands on the host system. For example, an API endpoint to ping a host specified by the user:
import subprocess
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/v1/ping', methods=['POST'])
def user_ping_func():
host = request.json.get('host')
try:
output = subprocess.check_output(f"ping -c 4 {host}", shell=True)
return jsonify({"success": "true", "output": output.decode()})
except subprocess.CalledProcessError as e:
return jsonify({"success": "false", "message": str(e)}), 500
This implementation is vulnerable to command injection. An attacker could exploit it with a payload like:
{
"host": "8.8.8.8; cat /etc/passwd"
}
The resulting command becomes:
ping -c 4 8.8.8.8; cat /etc/passwd
This would execute the ping command and then output the contents of the /etc/passwd
file, potentially exposing sensitive system information.
Improper Asset Management
Improper asset management in APIs refers to the lack of control and visibility over API endpoints, versions, and the data they expose. This security vulnerability usually stems from sloppy documentation, improper version control, or old API versions not being forcefully decommissioned.
A great example is exposing development or debug endpoints in a production environment. For example, there might be a hidden/test API endpoint like /api/v1/debug/users
that was used during the development to list all user data (hacky solutions used by developers).
If this endpoint is not removed or properly secured before deployment, an attacker would have just hit a gold mine of sensitive data.
In addition, APIs may inadvertently reveal more data than what is needed. A plaintext list of a user’s basic information might include their password hashes or some internal system identifier. If this were an endpoint that wasn’t ever really meant to be exposed, it would vastly increase the scope and scale of any leaked data.
Scan the API endpoints your web app consumes at no added cost with our Pentest plan
How to Pentest an API?
A fully complete API penetration test incorporates a variety of key techniques to address different aspects of security using an API penetration testing checklist. So, let’s consider these methods in detail.
Fuzzing APIs
API fuzzing consists of using a bunch of unexpected inputs (wordlists) to see how an API behaves. This is mostly used to fuzz a subdirectory or a subdomain using wordlists.
In practice, this involves:
- Listing all the API endpoints along with what they expect as parameters
- Creating a wide range of inputs such as sensitive files, special characters, and historically known attack patterns
- Auto-posting these inputs to the API
- Look at the replies for any abnormal behavior, errors, or crashes.
One of the most common tools used for fuzzing APIs is ffuf (Fuzz Faster U Fool). You can install ffuf using brew (on MacOS) using brew install ffuf and run it using the following command:
ffuf -w /path/to/wordlist -u https://target/FUZZ
For instance, if a user ID is expected by an API – you may test this out on inputs like these:
- A very long string of numbers
- User ID of another user
- SQL injection payloads such as “1 OR 1=1”
One of the most commonly used wordlists for fuzzing is SecLists, which is publicly available on GitHub.
Discovering APIs
Discovering APIs is like digital detective work. Many developers forget about APIs created during hackathons, PoC, or test solutions, making them undocumented features/backdoors that have been waiting to be exploited for years. Extracting these from the software involves:
1. Inspecting client-side code: View JavaScript files within a web browser and look for JS files or decompile APK files to extract API calls made by mobile apps.
2. Network traffic capturing: Tools to view all API calls an application makes can be used to discover APIs. Burp Suite or Zap (Zed Attack Proxy) can intercept network traffic and find APIs.
3. Enumerating Subdomains: APIs are usually hosted on subdomains, such as api.example.com or api-stg.example.com. Some of the most common tools for finding subdomains are amass and subfinder.
You can use amass using the following command:
amass enum -d example.com
Authorization Attacks
An authorization attack is all about getting at things that you should not have been allowed to do. Common techniques include:
- Horizontal privilege attacks: This type of attack is all about improperly accessing different user data on the same access level as yours. Some examples are changing the user ID in API requests to see other users profiles etc.
- Vertical privilege attacks: This could involve changing a user role in a token to allow access to high-privileged users such as admin.
- IDOR (Insecure Direct Object References): Modifying the identifiers for a resource in an API request to get at resources without authorization.
For example, this would be an IDOR in an API request to get order details GET /api/orders/1234
. Now, if we change it to GET /api/orders/1235
(someone else’s order), if it returns the order details of another user, it’s vulnerable to IDOR.
Authentication Attacks
These types of attacks are focused on the authentication phase – the process that ensures users are who they say on the login page when requesting services or data access. These attacks include:
1. Brute-Force Attacks: Trying hundreds of potentially valid username and password combinations in a systematic manner. Security engineers usually use Burp Intruder (extension of Burp Suite) or hydra for brute forcing. Here’s an example of what Burp Intruder looks like.
2. Token Manipulation: Forcing changes to tokens used for authentication, such as JWTs, to impersonate another user for increased privileges. One famous open-source tool for testing common attacks and CVEs is “jwt_tool”.
Sample command to use the tool:
python3 jwt_tool.py <JWT>
3. Improper token validation: The service can accept expired or malformed tokens, including an expired session or JWT token.
Injection Attacks in APIs
In Injection attacks, attackers incorporate malicious code into API Requests (different fields based on the attack). Common types include:
- SQL Injection: SQL commands are inserted into input fields to manipulate the database.
- NoSQL Injection: This is no different from SQL injection, but in this case, it is for a NoSQL database.
- Command Injection: To trick the API into processing system commands such
cat/etc/passwd
As an example, for a NoSQLinjection attack, you can post this login request :
{ username: { $ne: null }, password:{ $ne:null } }
This could enable you to log in as any existing user with a MongoDB-based API.
SQL Injection attacks are performed using SQLmap, a widely used tool that runs in Python and can be easily installed.
SSRF Attacks
The API server should not send its requests anywhere that it is told. It’s as if you are getting someone with special privileges to retrieve information for you from a secure space.
You might test for SSRF by:
- Finding API endpoints that serve external resources
- Also, by trying to access internal resources through these endpoints.
When doing it manually or with some help from proxies, try using multiple URL formats to dodge the filters.
For example, if the API can only get external images, you could try:
GET /api/fetch-image?url=http://localhost/admin-panel.
If the SSRF is successful, it could lead to accessing an internal admin panel.
Burp Collaborator is widely used to test OOB connections. It usually provides a URL like “[email protected]”, which can be used to get a pingback.
Best Practices to Avoid API Vulnerabilities
Input validation and sanitation
- Use strict input validation for all API parameters.
- Utilize a type and range spec, with whitelist validation of expected values.
- Filter inputs to avoid injection attacks, ensuring the security of an API.
Example Python code to validate username using regex:
import re
# sample function to validate username
def validate_username(username):
return re.match(r'xxxx', username) is not None
Strong Authentication
- Use standard auth protocols (OAuth2, OpenID Connect).
- Require two-factor authentication for sensitive operations.
- Always store encrypted passwords in DB.
Example of JWT configuration in Python:
const jwt = require('jsonwebtoken');
# sign the jwt token using SECRET (processed from env file)
const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, {
expiresIn: '1h',
algorithm: 'RS256'
});
Proper Authorization
- Use Role-based access control (RBAC) in applications.
- Always use the Principle of Least Privilege.
- Verify authorization on each API call.
Example of RBAC:
@app.route('/api/admin', methods=['GET'])
@jwt_required
def admin_endpoint():
if not current_user.has_role('admin'):
return jsonify({'error': 'Unauthorized'}), 403
# Admin logic here
Rate Limiting and Throttling
- Apply rate limiting to avoid misuse and DoS flood.
- Use algorithms such as leaky buckets to implement rate limits.
Error Handling and Logging
- Use proper error handling to prevent information disclosure.
- Provide generic error messages for clients.
- Detailed error logs on the server side.
Why Do Companies Prefer Astra for API Penetration Testing?
More and more companies are choosing Astra Security to conduct API penetration testing, thanks to its unique approach to advancing security technology.
The foundation of Astra’s offering is a hybrid methodology that uniquely combines automated scanning with manual expert analysis. This enhances the overall breadth of coverage beyond what automated tools or human testers can provide in isolation.
Astra includes an automated scanner capable of identifying over 9,300 vulnerabilities, covering the entire spectrum of vulnerabilities (from low to critical). However, incorporating human skills (our expert security engineers) differentiates Astra further, assigning worth to these insights.
The double vision is how the technology completely eliminates false positives. Astra saves brands precious time and resources chasing down false issues.
Some of the benefits which clearly stand out while pentesting APIs using Astra are :
- Hacker-like scanning capability with auto-evolution
- Integrate with CI/CD pipelines for shift-left security practices without slowing down development workflows
- A single comprehensive tool for vulnerability scanning, assessment, and response.
Most importantly, Astra has won the trust of industry leaders from several sectors. Astra has customers like Agora, Spicejet and Dream11 who trust the platform to efficiently protect their essential API infrastructure.
It is one small security loophole v/s your entire website or web application.
Get your web app audited with
Astra’s Continuous Pentest Solution.
Final Thoughts
API penetration testing has become crucial for fortifying systems against data breaches and financial losses by proactively identifying vulnerabilities like broken authentication, injection flaws, and improper asset management.
Moreover, a combined approach of automated scanning and expert analysis is paramount to building truly resilient API infrastructures.
FAQs
What is manual API penetration testing?
Manual API penetration testing is performed by security testers who manually send requests to the API and analyze the responses in order to look for security vulnerabilities.
How often do you conduct API penetration testing?
Ideally, API penetration testing should be conducted at least twice a year; however, this largely depends on various factors such as organization requirements, risk profile, and company compliance needs.
Who needs API penetration testing?
API penetration testing is important for API developers, providers, and consumers. Providers include companies that develop and share APIs with partners and customers, as consumers are organizations that use APIs in their applications or services.
Additional Resources on API Security: