Ever since PHP 5.5, web developers have relied on the robust password_hash() and password_verify() functions to safely manage user passwords. But in early 2024, security researchers discovered a critical bug: CVE-2024-3096. This flaw lets attackers authenticate as *any user* whose password hash starts with a null byte, simply by entering a blank password.

Let’s break down how this problem happens, why it’s dangerous, and what you must do right now to fix your PHP servers.

8.3.x before 8.3.5

In these versions, if a password is hashed using password_hash() and the resulting hash *starts* with a null byte (hex \x00), then calling password_verify() with a blank string will incorrectly validate as true—even if the actual password isn’t blank!

Usually, matching the blank password should fail for every user. But for affected hashes, attackers could sign in with an empty password and gain unauthorized access.

Technical Deep-Dive: Why Does It Happen?

PHP stores password hashes as strings, but underlying C code compares bytes. If the hash begins with "\x00...", then, during comparison, the null byte signals "end of string" in C, and only the first byte is considered. This means an empty string is seen as matching the hash's beginning—sneaking past the intended security.

Put simply: hashes starting with \x00 make blank passwords *always* validate.

Setup

<?php
$password = "not-empty";
$hash = "\x00" . password_hash($password, PASSWORD_DEFAULT);

// Save $hash to your “database”.
?>

> Note: This example forces the hash to start with a null byte for demonstration. In practice, this situation could arise through custom code or database corruption.

The Flaw in Action

<?php
// Simulate a “user login” check.
$stored_hash = /* fetch from database: e.g., "\x00$2y$10$...." */;
$user_input = ""; // Attacker enters a blank password

if(password_verify($user_input, $stored_hash)) {
    echo "Access granted: You're in!";
} else {
    echo "Access denied.";
}
?>

Expected: Only correct passwords work.
Actual on vulnerable PHP: A blank password passes. "Access granted: You're in!"

How Can This Happen in the Real World?

1. Database Corruption: Null bytes could creep in due to misconfigured serialization, backups, or export/import bugs.
2. Custom Code: Some custom login systems or plugins might mishandle binary data, resulting in a leading null byte in stored hashes.
3. User Enumeration: Attackers might scan accounts to find which hashes start with null, then sign in as those users with a blank password.

Try signing in as each user with a blank password.

3. If the application uses an affected PHP version and the user's password hash starts with a null byte, the login will succeed, giving you unauthorized access.

How Dangerous Is This?

While not all password hashes start with a null byte, *any* affected account is at risk of having its security bypassed—no brute-force required.

In other words: Even perfectly strong passwords are useless if this bug exists and the hash starts with \x00!

8.3.x: Upgrade to 8.3.5 or newer

Official PHP Release Changelogs

If possible, scan your user database for password hashes that begin with a null byte

<?php
// Example: scan hashes from users table
$users = /* fetch users from db */;
foreach($users as $user) {
    if(strlen($user['password_hash']) >  && $user['password_hash'][] === "\x00") {
        echo "User {$user['username']} has a vulnerable hash!\n";
        // Force a password reset or re-hash
    }
}
?>

> Pro Tip: Force affected users to reset their passwords after fixing the bug to guarantee full security.

References & Further Reading

- PHP Bug #82163
- PHP.net Security Updates
- Official CVE Record - CVE-2024-3096

Conclusion

A tiny bug—just a single null byte—threatened the security of user login systems worldwide through CVE-2024-3096. If you manage a website or application using PHP, patch your system now. Don’t let blank passwords be your downfall.

Stay safe, and always keep your software up to date!

*Share this post with your sysadmin or dev team if your PHP software handles logins—you might just save your business from a breach.*

Timeline

Published on: 04/29/2024 04:15:08 UTC
Last modified on: 06/10/2024 18:15:36 UTC