Behind the Bug: Password reset poisoning

Brandon Roldan
4 min readJun 6, 2022

--

Introduction

In this writeup, i will be explaining what password reset poisoning is, and show examples on it on real life projects. Lets get started

What is Password Reset Poisoning

Password reset poisoning is a technique whereby an attacker manipulates a vulnerable website into generating a password reset link pointing to a domain under their control.

It exists when a potentially user controlled data is used to generate a password reset link. That may be in the host header, or any headers, or even on parameters, as long as it is user controlled and is not filtered/check, it may result to Password Reset Poisoning. This commonly result to account takeover, but you can steal tokens, other than the password reset token.

I dont see that much attention regarding this bug. I can only find a few report (1 report) on https://huntr.dev about this vulnerability. So i decided to look for it myself, see how they exist and what they looks like behind the code. Now that we know what it is, let me show you some real life examples of it.

CVE-2022–0935

The first example is in live helper chat. Live helper chat is a ticketing system made with php. In the password reset functionality, this is the body of the email generated

It uses the $host variable as the host of the password reset link, and this is the declaration of the $host variable.

This is one of the most common case of password reset link poisoning, this is also known as host header injection. As you can see, it uses the $_SERVER[‘HTTP_HOST’] which according to the php documentation is the host header

And this header could be user controlled. Which makes it vulnerable. If we request a password reset, and change the host header, we can poison the password reset link allowing us to takeover other user’s account. Read the whole report here. https://huntr.dev/bounties/a7e40fdf-a333-4a50-8a53-d11b16ce3ec2/ . The maintainers are very responsive, and unlike the others, they fixed the bug.

Alerta

Second example, Alerta is an alerting system made with python and flask. This is how they generate the password reset email

Unlike before, it is not in the host header but rather, it uses the also potentially user controlled header, the Referrer header. The link function simply, combines all the parts of the url together

And that makes it vulnerable to password reset poisoning. You can read the whole report here. I reported this bug, three months ago, and it is still not fixed, so i decided to disclose it, in this writeup.

MantisBt

MantisBt or Mantis Bug Tracker is a bug tracking software made with php. This is how they generate the password reset email.

The password reset linked is generated using this string_get_confirm_hash_url function. Lets see what it does.

It returns the passwor reset url string. The host part of the url is obtained using the config_get_global( ‘path’ ).

This function get the global variable g_<variable name>. In our case, it get the global variable g_path. And i found this global variable in config_defaults_inc.php.

And the $t_host variable is set in this part of the code

Here, you can see that it uses $_SERVER[‘HTTP_X_FORWARDED_HOST’] which is X-Forwarded-Host header, if it is set. This header is commonly used by proxies and can be user controlled. So to test it out, i made a password reset request and added a X-Forwarded-Host header. I also, slightly modified it so it prints out the email in the response.

I also reported this bug three months ago, but got no response. Looking at their bug reports, i found out that someone already reported it before back in 2019 and just got ignored. https://mantisbt.org/bugs/view_all_bug_page.php

Ending

Before i started looking for password reset bugs, i only commonly test the host header, in black box approach, but this taught me alot. Password reset poisoning can also exist in other places. I hope you learnt something new. Thanks for reading.
Twitter: https://twitter.com/tomorrowisnew_
Discord: https://discord.gg/bugbounty

--

--

Responses (2)