https://hackerone.com/<hacker> returns a JSON response containing some informations about the
<hacker>, the parameter signal is returned as a high precision float number (up to 14 digits after the comma), the fractional part of this JSON parameter can be used to disclose some informations including the exact number of Resolved, Informative, and N/A reports submitted by the researcher as demonstrated in the following of the report.
The signal is calculated server-side by applying
(-5*N/A + 0*Informative + 7*Resolved) / (N/A+Informative+Resolved), self-closed reports and Duplicates are not included in signal calculations, I also ignored Spam reports because it's very rarely submitted by actif researchers. After the calculation is done, the signal value is returned as it is in
https://hackerone.com/<hacker> even if only 2 digits after the comma is shown in the hacker profile, for instance, the following GET request to @fransrosen profile
curl -H 'X-Requested-With: XMLHTTPRequest' -H 'Accept: application/json' https://hackerone.com/fransrosen will give us
Keeping in mind that the number of Resolved reports are publicly disclosed in the
report_count JSON parameter, it's enough to know Informative and N/A reports to have all the details about the hacker. To proceed, one should calculate x and y with
signal = x*(-5)+y*(0)+report_count*7 / x+y+report_count, note that the signal is a high precision float number so the equation won't have more than solution, especially if we designate an estimation of the max number of submitted reports, and that's what I did in my exploit.
While this cannot not be accomplished mathematically (AFAIK), it can be easily done brue-force.
I wrote a small python program to exploit this issue, the script can be used with the syntax :
python H1-signal.py <hacker> <max-reports>
<hacker> is the hacker to attack, and
<max-reports> is an estimation of the max number of reports submitted by him, the estimation can be made depending on the hacker profile, the script will make a call to
https://hackerone.com/<hacker> then recover the necessary parameters, then start the brute-force process, if
<hacker> has really submitted less than
<max-reports> reports, we will get the exact number of every submitted report by state.
Let's test on my own profile @666reda
1- make an estimation of the max report number submitted by @666reda, he has only 3 found bugs with 1.35 signal, so let's say 15 reports.
python H1-signal.py 666reda 15
3- after a few moments we got :
And that's my exact log, because
3 Informatives and
3 Resolveds is the only combination which produce the signal
Another test with ███████ and ████████ (sorry for this, please redact the names if you plan to publicly disclose the report, I already redacted them from the screenshot)
1- make an estimation of the max report number submitted the researchers.
python H1-signal.py xawdxawdx 25 && python H1-signal.py ronygigi 20
3- after a few moments we got :
these will be their submitted reports logs, because they are the only possibilities that can result the returned signal.
Linux kali 4.9.0 with Python 2.7.13 and curl 7.55.1.
Information Disclosure via knowing the exact log of submitted reports with no user interation.
It takes much time when it's about more that 30 reports, especially if we took into consideration Spam reports, so of course, not all hackers can be targeted by exploiting this bug. However, hundreds of H1 users has submitted less than 30 reports, and can be easily targeted, so I guess you still want to fix this, right ?
Do everything server-side and send back only the signal with 2 digits after the comma which will be directly displayed in the hacker profile, or include Duplicate reports in the signal calculation.
Let me know if you have any additional questions, Regards.