CVE-2026-25861 Overview
CVE-2026-25861 is a weak cryptographic algorithm vulnerability affecting QloApps through version 1.7.0. The flaw resides in the Tools::encrypt() function within classes/Tools.php, which uses MD5 to hash user passwords. The function concatenates a static cookie key with the supplied password before hashing, producing fast and brute-forceable digests. Attackers who obtain the password database can perform offline brute-force or rainbow-table attacks to recover plaintext credentials. The risk is amplified because classes/Customer.php auto-generates 8-character passwords during guest-to-customer account conversion, making credential recovery trivial. The issue is tracked under [CWE-916: Use of Password Hash With Insufficient Computational Effort] and was fixed in commit 64e9722.
Critical Impact
Offline brute-force recovery of QloApps user credentials due to MD5 password hashing combined with weak auto-generated 8-character passwords.
Affected Products
- QloApps through version 1.7.0
- classes/Tools.php — vulnerable Tools::encrypt() function
- classes/Customer.php — auto-generated 8-character passwords during guest conversion
Discovery Timeline
- 2026-06-02 - CVE-2026-25861 published to NVD
- 2026-06-02 - Last updated in NVD database
Technical Details for CVE-2026-25861
Vulnerability Analysis
QloApps stores customer passwords using MD5, a cryptographic hash function unsuitable for password storage. The Tools::encrypt() function concatenates a static application-wide cookie key with the user-supplied password and applies a single MD5 pass. MD5 is fast, unsalted per-user, and vulnerable to GPU-accelerated brute force. Modern hardware can compute billions of MD5 hashes per second, enabling rapid recovery of plaintext passwords from any leaked database. The static cookie key offers no protection because it is shared across all accounts and can be extracted from any compromised installation.
Root Cause
The root cause is the use of MD5 as a password hashing algorithm in Tools::encrypt() rather than a memory-hard, adaptive function such as bcrypt, scrypt, or Argon2. The passwd column in classes/Customer.php was sized at 32 characters, matching an MD5 hex digest, which architecturally locked the implementation to a fixed-length weak hash. The patch raises the column size to 60 to accommodate bcrypt output via the new PasswordHashing class.
Attack Vector
An attacker who obtains the QloApps user database through SQL injection, backup exposure, or insider access can crack credentials offline. Auto-generated 8-character passwords issued during guest-to-customer conversion fall within practical brute-force range against unsalted MD5. Recovered credentials enable account takeover, fraudulent bookings, and lateral access to administrator accounts that reuse the same hashing path.
// Patch: classes/AdminTab.php — replace MD5 Tools::encrypt with PasswordHashing
if ($key == 'passwd' && Tools::getValue('id_'.$table) && empty($value)) {
continue;
}
- /* Automatically encrypt password in MD5 */
+ /* Automatically hash password */
if ($key == 'passwd' && !empty($value)) {
- $value = Tools::encrypt($value);
+ $objHash = new PasswordHashing();
+ $value = $objHash->passwordHash($value);
}
$object->{$key} = $value;
Source: GitHub Commit 64e9722
// Patch: classes/Customer.php — passwd column grown from 32 to 60 chars for bcrypt
'email' => array('type' => self::TYPE_STRING, 'validate' => 'isEmail', 'required' => true, 'size' => 128),
- 'passwd' => array('type' => self::TYPE_STRING, 'validate' => 'isPasswd', 'required' => true, 'size' => 32),
+ 'passwd' => array('type' => self::TYPE_STRING, 'validate' => 'isPasswd', 'required' => true, 'size' => 60),
'last_passwd_gen' => array('type' => self::TYPE_STRING, 'copy_post' => false),
Source: GitHub Commit 64e9722
Detection Methods for CVE-2026-25861
Indicators of Compromise
- Database passwd column values that are 32 hexadecimal characters long, indicating raw MD5 hashes still in use.
- Anomalous authentication success patterns for guest-converted customer accounts following a database exposure event.
- Unexpected logins from new geolocations or user agents against QloApps customer or admin accounts.
Detection Strategies
- Audit QloApps installations for the presence of Tools::encrypt() calls referencing password fields in classes/Tools.php and classes/AdminTab.php.
- Compare deployed commits against the fixed commit 64e9722 to confirm the PasswordHashing class is in use.
- Inspect the customer table schema to confirm the passwd column size has been increased from 32 to 60 characters.
Monitoring Recommendations
- Monitor authentication logs for credential-stuffing patterns and high-velocity login attempts against QloApps endpoints.
- Alert on bulk export queries against the customer table or unusual access to database backups.
- Track guest-to-customer conversion events and flag subsequent successful logins from unfamiliar sources.
How to Mitigate CVE-2026-25861
Immediate Actions Required
- Apply the upstream fix in commit 64e9722 or upgrade to a QloApps release that includes pull request #1689.
- Force a password reset for all customer and administrator accounts so credentials are rehashed with bcrypt via the PasswordHashing class.
- Invalidate existing sessions and rotate the static cookie key referenced by the legacy Tools::encrypt() function.
Patch Information
The vulnerability is fixed in commit 64e9722 via GitHub Pull Request #1689. The patch replaces MD5-based hashing with a new PasswordHashing class and resizes the passwd column to 60 characters to accommodate bcrypt hashes. See the VulnCheck Advisory on QloApps for additional technical context.
Workarounds
- Enforce strong password complexity and minimum length requirements to reduce brute-force feasibility against legacy MD5 hashes.
- Disable or restrict the guest-to-customer conversion flow until the patch is applied to avoid issuing weak 8-character passwords.
- Place QloApps administrative paths behind network access controls and multifactor authentication to limit credential-replay impact.
# Verify QloApps is running the patched commit
cd /path/to/QloApps
git log --oneline | grep 64e9722
# Confirm passwd column has been resized to 60 characters
mysql -u <user> -p <database> -e "DESCRIBE ps_customer;" | grep passwd
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

