๐ Heyo Internet!
I am debang5hu, and over here I'll be sharing my findings and methodology from a recent security assessment on target.com. This write-up covers the vulnerabilities I identified and how they can be chained together to achieve real-world impact.
- Unrestricted File Upload leads to Stored XSS
- Brute-Force Login + Weak Password Policy = high
- Password Reset Token Mismanagement
- User Enumeration via Forgot Password
Let's dive in!
Unrestricted File Upload leads to Stored XSS:
The application relies on the Content-Type: application/pdf header for validating uploads, which can be easily spoofed. By intercepting a file upload request in Burp Suite, I replaced the file with a HTML file with the content </script>alert("xss");</script> and modified the content type to application/pdf. The server accepted the upload and returned a file path. The uploaded file was hosted on a different subdomain ( api.target.com), and accessing this file via the provided URL caused the HTML to render in the browser, executing embedded JavaScript.
Curl PoC:
# to upload (arbitrary file can be uploaded)
curl -X POST -H "Origin: https://www.target.com" https://api.target.com/gap-service/api/gaps/upload -F "file=@main.html;type=application/pdf"
{"url":"/uploads/1770290985072-main.html"}
# to access
curl -H "Origin: https://www.target.com" https://api.target.com/gap-service/uploads/1770290985072-main.html
</script>alert("xss");</script>This behavior constitutes an unrestricted file upload combined with broken access control, leading to unauthorized data storage, hosting of malicious content, and potentially be abuse for data exfiltration.
Bruteforce on Login Page and Weak Password Policy may lead to ATO:
The login endpoint /user-service/api/users/login does not implement any rate limiting or lockout mechanism. I tested this by repeatedly attempting login with incorrect passwords for a valid account. Even after 71 failed attempts, the application continued to process requests without restriction. On the next attempt using the correct password, authentication succeeded.
Also, The application does not enforce basic password security standards. During testing, I was able to set extremely weak passwords (e.g., 1234 , password , or even password like 1 ) during account creation or password change.
Which significantly reduces the effort required for a successful brute-force attack if the user uses weak credentials.
Password Reset Token Reuse Due to Improper Invalidation:
In the password reset flow ( /user-service/api/users/reset-password ), a reset token is issued after OTP verification. However, generating a new token does not invalidate previously issued ones. I initiated the reset process and obtained a token (T1), then repeated the process to generate a second token (T2). Instead of using T2, I used T1 to reset the password, and the request was still accepted. In some cases, sending the request multiple times ensured success.
Steps to Reproduce:
- Initiate the forgot password flow for a valid user account.
- Complete OTP verification and obtain a password reset token (Token T1).
- Do not use T1 to reset the password.
- Initiate the forgot password flow again for the same account.
- Complete OTP verification again and obtain a new password reset token (Token T2).
- Proceed to the password reset endpoint.
- Instead of using T2, submit the password reset request using the older token T1.
- Observe that the password reset request is successfully accepted, and the password is changed.
User Enumeration via Forgot Password:
The forgot-password functionality endpoint /user-service/api/users/forgot-password returns different responses based on whether an email exists. Submitting a valid email returns a 200 OK response with OTP sent , while an invalid email returns 404 Not Found with User not found.
๐ Overall, this was a really interesting assessment โ I really enjoyed discovering and exploiting these bugs.
Sayonara!!!