CVE-2016-9124 (PHP, published 2017-03-28T02:59Z)
Description: value: Revive Adserver before 3.2.3 suffers from Improper Restriction of Excessive Authentication Attempts. The login page of Revive Adserver is vulnerable to password-guessing attacks. An account lockdown feature was considered, but rejected to avoid introducing service disruptions to regular users during such attacks. A random delay has instead been introduced as a countermeasure in case of password failures, along with a system to discourage parallel brute forcing. These systems will effectively allow the valid users to log in to the adserver, even while an attack is in progress.
Severity: MEDIUM (CVSS v3 base score: 9.8)
Weakness: CWE-287 \u2014 Improper Authentication
When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.
Repository: https://github.com/revive-adserver/revive-adserver
Files changed:
lib/OA/Auth.php
lib/OX/Extension/authentication/authentication.php
Commit message: Mitigate h1 report 96115

Improper Restriction of Excessive Authentication Attempts
---------------------------------------------------------

Karan M. Tank and Smit B. Shah have reported via HackerOne that the login
page of Revive Adserver was vulnerable to password-guessing attacks. An
account lockdown feature was taken into account, but rejected to avoid
introducing service disruptions to regular users during such attacks.
A random delay has been introduced as a counter-measure in case of password
failures, along with a system to discourage parallel brute forcing. Such
system will effectively allow the actual user to log in to the adserver even
while an attack is in progress.

A CVE-ID has been requested, but not assigned yet.

CWE: CWE-307
CVSSv2: 8.5 (AV:N/AC:L/Au:N/C:C/I:P/A:N)


Vulnerable code:
                sleep(3);
        $doUser->username = strtolower($username);
        } else {
            return false;
?>

Fixed code:
require_once MAX_PATH . '/lib/OA/DB/AdvisoryLock.php';
        // Introduce a random delay in case of failures, as recommended by:
        // https://www.owasp.org/index.php/Blocking_Brute_Force_Attacks
        //
        // The base delay is 1-5 seconds.
        $waitMs = mt_rand(1000, 5000);

        $oLock = OA_DB_AdvisoryLock::factory();

        // Username check is case insensitive
        $username = strtolower($username);

        // Try to acquire an excusive advisory lock for the username
        $lock = $oLock->get('auth.'.md5($username));

        if (!$lock) {
            // We couldn't acquire the lock immediately, which means that
            // another authentication process for the same username is underway.
            //
            // This might mean that the account is being targeted by a
            // multi-threaded brute force attack, so we try to discourage such
            // behaviour by increasing the delay time by 4x.
            //
            // However, if the actual user tries to log in while their account
            // is being attacked, we will allow them in, they'd just have to
            // be patient (max 20 seconds).
            usleep($waitMs * 4000);
        }

        $doUser->username = $username;

            $oLock->release();


        if ($lock) {
            // The password was wrong, but no other login attempt was in place
            // so we apply just the base delay time.
            usleep($waitMs * 1000);
        }

        $oLock->release();

        return false;

class Plugins_Authentication_Exception extends Exception
{
}