VAmPI Walkthrough
Consider this as a Pentest Report (Findings Section) for the VAmPI.
Find this project on Github here.
SQL Injection
The application is vulnerable to a SQL Injection vulnerability. A custom SQL Query could be appended after the username in the /users/v1/ endpoint to execute the same in the backend SQLite Database. An anonymous attacker can dump the database containing the user credentials and the books with all the secrets. This could result in a massive data breach.
CVSS Score: 9.8
Steps to Reproduce:
Add a single quote in the end of the username in the /users/v1/ endpoint. Observe that an error occurred in the SQL Query. Also, a secret key is exposed in the response without any context.
Running the same request through SQLMap, we can find that there are 2 tables in the database: Books and Users. Both of them can then be dumped. The below screenshot shows the dumped Users table.
Solution:
Typical SQL Injection arises because the user controlled input is concatenated to a SQL Query in the backend code without any sanitization. To fix this issue consider using parameterized queries for handling such inputs instead of simply concatenating it.
Sensitive Data Exposure
The application simply allows any unauthenticated user to use the debug endpoint to query the list of users and the associated passwords. An attacker can easily find this endpoint out through brute forcing and get hold of user credentials. This could then be used to gain Admin level access to the application and remove a legitimate user.
CVSS Score: 9.8
Steps to Reproduce:
Just query the _debug endpoint.
Solution:
Decommission the /_debug endpoint. Also consider storing the user’s password as salted hashes instead of clear text.
Broken Access Control
Scenario 1
The JWT Token issued when the user logs in has a very weak security key. This can easily be cracked through tools like Hashcat. After cracking the JWT, an attacker can issue a forged token on behalf of the admin and can gain Administrator level privileges on the application.
The attacker can now delete any user from the application causing a denial of service for that legitimate user.
CVSS Score: 8.8
Steps to Reproduce:
Login to the application as an attacker.
Take the JWT token that was issued in the response of the login request and run HashCat on it. Observe that HashCat cracks it.
Issue a new JWT Token for the admin user using jwt.io and use it to send the request to delete a user. Observe that the forged token is accepted and the user gets deleted.
Scenario 2
The application is vulnerable to a Mass Assignment vulnerability in the Registration Endpoint, through which an attacker can gain an elevated privilege. Exploiting this, the attacker can delete any other victim user causing a disruption of service for them.
CVSS Score: 8.1
Steps to Reproduce:
Send the Sign Up request and add a custom parameter in the body with the key pair “admin”: true. Observe that the request gets accepted and a new account is created.
The same steps (as mentioned above) can be followed to delete the victim user.
Scenario 3
The application simply allows a user to view not only the books of other users, but also the Secrets associated with them. This should not be allowed by default and poses a serious threat of sensitive data exposure.
CVSS Score: 6.5
Steps to Reproduce:
Enumerate the list of books present.
Login to the application as an attacker and query the specific book by the name. Observe that there is the secret string also shown along with the book.
Solution
Consider changing the secret for issuing JWT token to something strong and complex. Or, it’ll be better to use RS256 Algorithm instead of HS256.
Consider filtering the fields based on a whitelist of allowed objects that the user can add in the request.
Design and enable permission based access control. Do not allow users to refer to an object directly without any permission check.
Username Enumeration
The application shows a custom message during the registration process which exposes the presence of such user in the application’s database. This can be used by an attacker to do a brute force attack on the login functionality. The application does not enforce the usage of complex passwords either. If a user has a simple password, his account is vulnerable to be hijacked.
CVSS Score: 5.6
Steps to Reproduce:
Give an existing username as an input. Observe that the application shows that this user already exists.
Brute force the login request with the same username and a wordlist in the password field. Observe that we have a differing response on the correct password.
Solution:
Consider not sharing a detailed response whether a user exists or not. Just let the registering user know whether the provided username is applicable or not in a very generic way. Also consider implementing a brute force protection like Captcha or Temporary Auto Lock on the login functionality. It is also recommended to implement the requirement of complex passwords instead to something right from the dictionary.
Username Collision
It was found that the application does not properly sanitize the username during the registration process. An attacker can create a fake account with the victim’s name by appending a blank space after the username. The attacker can then spread unwanted / malicious books to the other users by uploading them on the application, causing a reputation loss to the victim.
CVSS Score: 5.3
Steps to Reproduce:
Just input the victim’s username and append a blank space in the last. Observe that the account is created and can be accessed.
Solution:
Consider sanitizing the username strings provided by the users.
Logical Misconfiguration leading to Denial of Service
The application does not perform a sanitization on the data passed on the email parameter on the /users/v1/:username/email endpoint. If a large string (30 characters long) is passed as the email, the application stops responding and becomes temporarily unavailable. This could result in a disruption of service for a legitimate user.
CVSS Score: 4.3
Steps to Reproduce:
Login to the application and craft a email updation request. Put any string around 30 characters long as the value of the email parameter. Send the request and observe that the application goes down.
Solution:
Make sure that the user input for the email parameter is sanitized for appropriate character and length before processing it in the backend code.
Conclusion
The VAmPI Vulnerable API is a practical tool for understanding and testing the most commonly found vulnerabilities in APIs. It offers a hands-on approach to learning about API security, making it useful for both beginners and experienced testers. The walkthrough covers key vulnerabilities, demonstrating their occurrence, detection, and prevention. I have tried to combine the vulnerabilities as much as possible and create a greater impact on the application’s infrastructure. Remember, security threats evolve constantly, so continuous learning is crucial.
Lets get in touch: Add me on Linkedin.