Full Report
Gitlab is a platform similar to Github. Recently, a user found an awful password reset issue that borks the security of the entire system. I love the beginning sentence from the DayZeroSec folks: "Dyanmic typing strikes again!" Languages like Java, C# and others are super serious on data structures being passed in. In Ruby, PHP, Python and others, there are virtually no rules. I've definitely written code over the years that returns different types in different situations, which I know I shouldn't do though. When passing in an array for the email instead of a string, weird things happened. The lookup function for emails took in an array OR a string. This lookup would only parse the first email in the list though. When actually sending out the password reset tokens, all of the emails in the array would be used. According to Z on the audio version of the podcast, the function for parsing the email to reset had email in the name while the second one had emails in it. Using this, an attacker can trigger a password reset on a victim that will send the link to their own email. To fix this issue, you can't even specify an email anymore. Instead, it's derived from the user record itself, which is much more secure. How do people find this types of bugs!? Gotta love the creativity of these folks.
Analysis Summary
## Vulnerability: GitLab Account Takeover via Password Reset Email Misdirection
## CVE Details
- CVE ID: Not specified in the provided text.
- CVSS Score: Not specified.
- CWE: Likely related to Improper Input Validation or Type Confusion, stemming from Dynamic Typing vulnerabilities.
## Affected Systems
- Products: GitLab
- Versions: Not specified (the vulnerability was patched via a commit).
- Configurations: Systems where the password reset functionality was exposed and handled dynamic typing incorrectly (allowing array inputs where a string was expected for the target email).
## Vulnerability Description
The vulnerability resides in GitLab's password reset mechanism, stemming from the flexibility of dynamic typing (Ruby). When initiating a password reset, the system expected an email address as a string. However, due to improper validation allowing an array of emails to be passed:
1. **User Lookup:** The initial lookup function only processed the *first* email provided in the array to find the corresponding user account.
2. **Token Sending:** After identifying the victim's account based on the first email, the subsequent function responsible for sending the reset token accepted the *entire array* of provided emails as the destination(s).
This logic flaw allowed an attacker to provide an array containing the victim's email address as the first element (to find the correct user) and their *own* email address as subsequent elements. The password reset token would then be sent to **all** emails in the array, effectively redirecting the token to the attacker.
## Exploitation
- Status: Implied to be a publicly disclosed flaw discovered by a user ("DayZeroSec folks"). Exploitation details are not specified if it was exploited in the wild, but a PoC is implied via the description of the input manipulation.
- Complexity: Low (requires sending a malformed request during password reset).
- Attack Vector: Network.
## Impact
- Confidentiality: High (Enables unauthorized access to the victim's account via token interception).
- Integrity: High (Allows an attacker to reset the password and gain full control/integrity over the account).
- Availability: Low (Indirect impact, primarily focused on user account security).
## Remediation
### Patches
- The specific patch removed the ability for users to explicitly specify the destination email address during a password reset. The system now derives the destination email solely from the verified user record itself.
- Reference Commit: `abe79e4ec437988cf16534a9dbba81b98a2e7f18`
### Workarounds
- No specific workarounds are detailed, but organizations should immediately apply the patch. If patching is delayed, review or restrict access to the password reset endpoint where possible, though this is highly disruptive.
## Detection
- Indicators of Compromise: Unusual outbound email traffic from the GitLab server originating from password reset requests targeting known user accounts where the destination email did not match the user's primary registered address.
- Detection methods and tools: Log analysis of password reset requests looking for input fields containing email arrays rather than single string values for the target email parameter.
## References
- Vendor Advisory/Commit: `https://gitlab.com/gitlab-org/gitlab/-/commit/abe79e4ec437988cf16534a9dbba81b98a2e7f18`
- Source Code Context: `https://gitlab.com/gitlab-org/gitlab/-/blob/a935d28f3decf8f6873d5b0a6f405f2687d0f99f/app/models/concerns/recoverable_by_any_email.rb`