Before starting this article, make sure you are up to speed with Part 1.
Welcome back!
After successfully proving and exploiting OWASP vulnerabilities 1 to 5 in part 1, I am now tackling the remaining 5 OWASP API Security Top 10 2019 vulnerabilities. Plus, I am also solving the 3 additional side quests in vAPI.
After setting up the same way as I did in part 1, I simply ran: sudo docker compose up -d and proceeded as follows:
Mass Assignment occurs when an API blindly updates an object in the database with client-provided data (e.g., a JSON payload) without filtering out restricted fields. This allows attackers to inject parameters they should not have access to, such as account balances or administrative roles.
In vAPI, the user registration endpoint directly maps the incoming JSON payload to the database model, failing to restrict or whitelist the fields a user can set during account creation.
I started by creating a standard user account to see what fields are normally processed.
I then verified my profile by sending a GET request using the generated token to see the stored data structure.
To test for Mass Assignment, I created a new user, but this time I manually injected the "credit" field into the JSON payload with a high value.
I requested the profile data for this new user to confirm whether the backend had saved the injected value.
The API returned the details of the newly created account, confirming the injected parameter was processed successfully.
Triggering this logic revealed the flag: "flag{api6_afb969db8b6e272694b4}".
This task hinted at Cross-Origin Resource Sharing (CORS). Improperly configured Cross-Origin Resource Sharing policies allow unauthorized external websites to interact with the API on behalf of an authenticated user. This vulnerability typically occurs when servers use wildcards or dynamically reflect the user-supplied Origin header back in the Access-Control-Allow-Origin response header, rather than validating it against a strict whitelist.
In vAPI, the endpoint intended to serve the user's secret key blindly trusts external origins and improperly combines wildcards with enabled credentials, completely defeating browser-based Same-Origin Policy (SOP) protections.
I started by creating a new user account to establish a valid identity on the system.
I then logged in as the newly created user to obtain an active session and authenticate my subsequent requests.
I used the GET key endpoint to retrieve the user authorization key. Upon inspecting the HTTP response, I noticed a highly permissive CORS configuration that is insecure.
To prove the CORS vulnerability was exploitable, I sent this GET request to the Burp Suite Repeater tool. I manually added an external origin to the HTTP request headers to see if the server would accept it.
Injection flaws, such as SQL Injection (SQLi), occur when untrusted user input is sent directly to an interpreter (like a database) as part of a query without proper sanitization or parameterization. This allows attackers to manipulate the backend query logic to execute arbitrary commands.
In vAPI, the API 8 login endpoint takes the username and password from the JSON payload and concatenates them directly into the underlying database query, leading to a massive data breach.
I started by attempting to log in with empty credentials, which returned an incorrect login response. I then tried again, injecting a classic SQL payload into the username field.
With MySQL backend confirmed, I decided to use the automated exploitation tool SQLmap. I created a text file named api8.txt containing the raw HTTP POST request and placed an asterisk (*) right after the test username to act as a custom injection marker for the tool.
I ran the SQLmap command targeting the text file to automate the extraction of the database contents.
Even though the SQL dump already provided the API 8 flag, I extracted the administrator credentials (admin / z2Eav@j6A:^}fsMe) from the api8_users table and used them to log in legitimately.
The database dump also leaked sensitive information for API 2 users (country, city, email, password, name, address, flags), API 7 users, API 5 users, and API 3 comments.
Improper Assets Management occurs when an application exposes older, deprecated, or unpatched versions of an API (shadow APIs) that lack the security controls implemented in the current production version.
In vAPI, while the current v2 login endpoint restricts brute-force attempts with rate limiting, an older v1 endpoint was left active on the server and completely unprotected.
I started by attempting to log in to the default v2 endpoint. The attempt was unsuccessful, and upon inspecting the HTTP response headers, I noticed rate limiting was being actively enforced.
To test for Improper Assets Management, I modified the URL path, switching from the secure v2 version back to a legacy v1 version.
I used ffuf along with a custom 4-digit wordlist (otp.txt) to fuzz the PIN for the user richardbranson on the vulnerable v1 endpoint. I filtered out incorrect attempts using the -fs 0 flag.
ffuf -w otp.txt -X POST -d '{"username":"richardbranson","pin":"FUZZ"}' -H "Content-Type: application/json" -u http://127.0.0.1:8000/vapi/api9/v1/user/login -fs 0
With the correct code obtained, I sent a POST request to the v1 login endpoint using the newly discovered PIN to authenticate.
Insufficient Logging and Monitoring occur when an application fails to track, record, or alert on critical security events. This includes failed login attempts, unauthorized access requests, or massive data extractions.
In vAPI, this final endpoint serves as a conceptual conclusion, explicitly acknowledging that the application lacked the monitoring capabilities necessary to detect the previous attacks.
I sent a standard, authenticated GET request to the final target endpoint to evaluate if the application had been tracking my previous intrusive activities.
JSON Web Tokens (JWTs) are commonly used for stateless session management. They rely on a cryptographic signature to ensure the payload (which often contains user IDs and roles) has not been tampered with by the client. However, a classic implementation flaw occurs when the backend validation library is misconfigured to trust the "alg": "none" directive in the token's header. This instructs the server to skip signature verification entirely.
In vAPI's "Just Weak Token" side quest, the application accepts the none algorithm, allowing a standard user to forge a token, elevate their privileges, and access administrative endpoints without needing a valid cryptographic signature.
I created a user account to obtain a valid, signed JWT from the server.
I copied the assigned token and pasted it into xjwt.io for analysis.
The decoded header showed that the token was originally signed using the "HS256" algorithm, and the decoded payload confirmed my standard permission level with role: "user".
To exploit the signature verification flaw, I manipulated the decoded JSON data directly in xjwt.io.
I replaced my original Authorization-Token header with the newly forged, unsigned token and attempted to access the protected GET endpoint.
Server-Side Request Forgery (SSRF) occurs when a web application fetches a remote resource without validating the user-supplied URL. This allows an attacker to coerce the application to send a crafted request to an unexpected destination, even bypassing firewalls to access internal networks or the local file system.
In vAPI's "Server Surfer" side quest, the application accepts a URL parameter, fetches the content at that URL, and returns it to the user as Base64-encoded data. It fails to restrict protocol wrappers, allowing attackers to replace standard HTTP requests with local file system requests.
I started by sending a standard request to the endpoint using a legitimate, external web address to understand how the application processes external URLs.
To test for SSRF and local file access, I modified the URL parameter to use the file:// protocol wrapper, targeting a common Linux system file.
I decoded the returned Base64 string using an online tool to verify if the server read its own internal file.
The decoded text revealed the exact contents of the server's /etc/passwd file, definitively proving the SSRF vulnerability.
Knowing I had arbitrary file-read capabilities, I changed the payload to target the root flag file.
Stored Cross-Site Scripting (XSS) occurs when an application receives untrusted user input, fails to validate or sanitize it, and permanently stores it on the server (e.g., in a database). The malicious payload is later served to other users or administrators who view that data. If a browser renders this data as HTML, the injected script executes within the context of the victim's session.
In vAPI's Sticky Notes side quest, the application accepts JSON-formatted notes, stores them, and provides a feature to retrieve them wrapped in XML/HTML tags. Because it does not sanitize the input upon creation or encode the output upon retrieval, it is highly vulnerable to Stored XSS.
I created a benign note to understand how the API processes and stores the data.
I then sent a GET request to retrieve the created note to observe how the server formats the output.
To test for Stored XSS, I crafted a new POST request and injected a classic JavaScript alert payload directly into the "note" parameter.
To prove the vulnerability, the payload needed to be reflected unescaped. I sent another GET request using the format=html parameter to retrieve the newly injected note.
I very much hope you found value in this walkthrough. See you in the next one.