Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG) in postfixadmin/postfixadmin
Reported on
Aug 2nd 2021
✍️ Description
uniqid
is used as input to MD5
when generating a PFA_TOKEN
(I'll refer to this as a session token) - the function uniqid
is not a CSPRNG but rather is a PRNG meaning that it cannot generate cryptographically reliable/secure values.
🕵️♂️ Proof of Concept
Execute the below code:
<?php
for ( $i = 0; $i < 50; $i++ ) {
$val = uniqid( "", true );
echo "#$i: ".$val." = \"".md5( $val )."\"</br>";
}
?>
Notice how the values on the right may seem random, the ones on the left are incredibly similar and would prove easy for an attacker to guess/brute-force.
💥 Impact
This vulnerability is capable of being able to take over user-sessions by brute-forcing PFA_TOKENs.
Occurrences
@admin in response to the issue that was automagically opened as the bot couldn't find a SECURITY.MD, the maintainer has created one that says 'GingerDog' or 'cboltz' can be contacted via the email that can be found in their git changelogs.
From git log
in my terminal, it seems like their emails are david@codepoets.co.uk
& postfixadmin@cboltz.de
so I'm not sure if you need to send them huntr.dev maintainer links via those email addresses manually as they aren't on the new SECURITY.MD
page.
Hey Michael, you're right, our process is to check up on these created issues and then manually send them the magic maintainer links.
Will be getting on this right now; I'll update you once emails have been sent.
That's good to hear, I thought it was all automated (some sort of callback when a SECURITY.MD was created maybe and then REGEX that file for a email)
Hey Michael, just sent them both an email. Thanks for your proactivity.
And you're right again by the way - if an email is detected, we'll send them the links automatically. Else, we will manually facilitate!
Hi - thanks for reporting the issue. I appreciate having someone else look at the code and help make it more secure for everyone.
PostfixAdmin uses the session variable 'PFA_token' as a means of preventing a CSRF request. The value of the PFA_token should be embedded in pages where someone may be submitting a form..... when the form is submitted we check that the submitted value of the PFA_token matches up with what is in the session.
I'll change the code to include random_bytes(8) so there's more random-ness used in the PFA_token value, but it feels like it'd be hard to trigger/exploit this in any case.
So if you're able to accurately tell what the time on the server is, you could therefore presumably calculate what the uniqid value would be, and therefore the md5 value used in the page .... and hence perform a CSRF request.
I'm not quite sure I'd agree with :
"This vulnerability is capable of being able to take over user-sessions by brute-forcing PFA_TOKENs."
I could see some additional randomness might be desirable to avoid a possible CSRF issue though.
Ergh, sorry, my reply is a bit jumbled up - I think I lost some of what was in the text box or something.
Better version :
I think this only affects the CSRF protection we have in place.
I'll change the code to use more entropy in the population of the PFA_token value.
I think this would be difficult to exploit, unless you could tell the exact time someone logged into Postfixadmin.
Ah you're right, I thought that PFA_TOKENs were session tokens and therefore had a higher value than they actually do - I can't think of any reasonable way to exploit this as I looked into injecting CSRF tokens into requests but couldn't find a reliable way to do so (with JavaScript at least). The severity of this report is way higher than it should be due to the tokens only being CSRF tokens, I'm not sure I can manually lower the severity of this report but if you or @admin could I'd appreciate it!
Also, would it be possible for you to validate the report and mark your commit (25ac89f6a7a51b34043fad388b7f81e4e07994e9) as the fix?
@michael - let me know what CVSS would be preferred here, and we can adjust!
Yeah that seems fine, a score of 3.0 is what I calculated given the adjustments in scope.