Revive Adserver · Report #3434156
Username Validation Bypass
How it was found
Cricetinae
Executive Summary
The security patch in commit d239a0845e4f64fbacd25fff2854426734d43aa2 is INSUFFICIENT.
Testing confirms that 3 out of 4 exploit vectors still bypass validation.
Vulnerability Details
Affected Component: Username validation in user registration/creation
File: lib/OA/Admin/UI/UserAccess.php
Line: 116
Current Pattern: #[\x00-\x1F\x7F\s]#u
Severity: Medium-High (CVSS 6.5) Impact: Account impersonation, phishing, validation bypass
Proof of Concept - Working Exploits
Exploit 1: Zero-Width Space (U+200B) CRITICAL
Description: Invisible Unicode character that creates duplicate accounts
Payload (Hex): 61646d696ee2808b
Payload (Decoded): admin + 0xE2 0x80 0x8B (UTF-8 for U+200B)
Payload (Literal): The username "admin" followed by Unicode character U+200B
How to reproduce:
$malicious_username = "admin" . "\xE2\x80\x8B"; // Hex bytes
// OR
$malicious_username = "admin" . mb_chr(0x200B, 'UTF-8'); // Unicode codepoint
Test code:
<?php
$username = "admin" . "\xE2\x80\x8B"; // admin + Zero-Width Space
echo "Username: admin[U+200B]\n";
echo "Hex bytes: " . bin2hex($username) . "\n";
echo "Expected: 61646d696ee2808b\n\n";
// Test against patched pattern
if (preg_match('#[\x00-\x1F\x7F\s]#u', $username)) {
echo "Result: BLOCKED ✓\n";
} else {
echo "Result: PASSES - VULNERABLE! ✗\n";
}
?>
Expected output:
Username: admin[U+200B]
Hex bytes: 61646d696ee2808b
Expected: 61646d696ee2808b
Result: PASSES - VULNERABLE! ✗
Impact:
- Creates account that looks identical to "admin" visually
- Bypasses username uniqueness constraints
- Enables account enumeration attacks
- Perfect for impersonation attacks
Exploit 2: RTL Override (U+202E) HIGH
Description: Right-to-Left Override mark that reverses text display direction
Payload (Hex): 61646d696ee280ae74657374
Payload (Decoded): admin + 0xE2 0x80 0xAE + test
Payload (Literal): The text "admin" + U+202E + "test"
How to reproduce:
$malicious_username = "admin" . "\xE2\x80\xAE" . "test"; // Hex bytes
// OR
$malicious_username = "admin" . mb_chr(0x202E, 'UTF-8') . "test"; // Unicode
Test code:
<?php
$username = "admin" . "\xE2\x80\xAE" . "test"; // admin + RTL Override + test
echo "Username: admin[U+202E]test\n";
echo "Hex bytes: " . bin2hex($username) . "\n";
echo "Expected: 61646d696ee280ae74657374\n";
echo "Visual display: 'tset' + 'admin' (reversed!)\n\n";
// Test against patched pattern
if (preg_match('#[\x00-\x1F\x7F\s]#u', $username)) {
echo "Result: BLOCKED ✓\n";
} else {
echo "Result: PASSES - VULNERABLE! ✗\n";
}
?>
Expected output:
Username: admin[U+202E]test
Hex bytes: 61646d696ee280ae74657374
Expected: 61646d696ee280ae74657374
Visual display: 'tset' + 'admin' (reversed!)
Result: PASSES - VULNERABLE! ✗
Impact:
- Text appears reversed in UI ("testadmin" displays as different order)
- Confuses administrators reviewing user accounts
- Enables social engineering attacks
- Visual spoofing in logs and admin panels
Exploit 3: Cyrillic Homograph (U+0430) CRITICAL
Description: Cyrillic letter 'а' (U+0430) that looks identical to Latin 'a' (U+0061)
Payload (Hex): d0b0646d696e
Payload (Decoded): 0xD0 0xB0 + dmin
Payload (Literal): Cyrillic 'а' (U+0430) followed by Latin "dmin"
How to reproduce:
$malicious_username = "\xD0\xB0" . "dmin"; // Hex bytes
// OR
$malicious_username = mb_chr(0x0430, 'UTF-8') . "dmin"; // Unicode
Test code:
<?php
$username = "\xD0\xB0" . "dmin"; // Cyrillic а + Latin dmin
echo "Username: [U+0430]dmin (looks like 'admin')\n";
echo "Hex bytes: " . bin2hex($username) . "\n";
echo "Expected: d0b0646d696e\n";
echo "Visual: Appears identical to 'admin'\n\n";
// Compare with real admin
$real_admin = "admin";
echo "Real 'admin' hex: " . bin2hex($real_admin) . "\n";
echo "Looks same? YES | Hex same? NO\n\n";
// Test against patched pattern
if (preg_match('#[\x00-\x1F\x7F\s]#u', $username)) {
echo "Result: BLOCKED ✓\n";
} else {
echo "Result: PASSES - VULNERABLE! ✗\n";
}
?>
Expected output:
Username: [U+0430]dmin (looks like 'admin')
Hex bytes: d0b0646d696e
Expected: d0b0646d696e
Visual: Appears identical to 'admin'
Real 'admin' hex: 61646d696e
Looks same? YES | Hex same? NO
Result: PASSES - VULNERABLE! ✗
Complete Test Script
Save this as test_vulnerability.php and run with php test_vulnerability.php:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
echo "========================================\n";
echo "Revive Adserver - Vulnerability Test\n";
echo "========================================\n\n";
// Test 1: Zero-Width Space
echo "[TEST 1] Zero-Width Space (U+200B)\n";
echo "----------------------------------------\n";
$test1 = "admin" . "\xE2\x80\x8B";
echo "Payload hex: " . bin2hex($test1) . "\n";
echo "Expected: 61646d696ee2808b\n";
echo "Match: " . (bin2hex($test1) === "61646d696ee2808b" ? "YES ✓" : "NO ✗") . "\n";
$blocked1 = preg_match('#[\x00-\x1F\x7F\s]#u', $test1);
echo "Status: " . ($blocked1 ? "BLOCKED ✓" : "VULNERABLE ✗") . "\n\n";
// Test 2: RTL Override
echo "[TEST 2] RTL Override (U+202E)\n";
echo "----------------------------------------\n";
$test2 = "admin" . "\xE2\x80\xAE" . "test";
echo "Payload hex: " . bin2hex($test2) . "\n";
echo "Expected: 61646d696ee280ae74657374\n";
echo "Match: " . (bin2hex($test2) === "61646d696ee280ae74657374" ? "YES ✓" : "NO ✗") . "\n";
$blocked2 = preg_match('#[\x00-\x1F\x7F\s]#u', $test2);
echo "Status: " . ($blocked2 ? "BLOCKED ✓" : "VULNERABLE ✗") . "\n\n";
// Test 3: Cyrillic Homograph
echo "[TEST 3] Cyrillic Homograph (U+0430)\n";
echo "----------------------------------------\n";
$test3 = "\xD0\xB0" . "dmin";
echo "Payload hex: " . bin2hex($test3) . "\n";
echo "Expected: d0b0646d696e\n";
echo "Match: " . (bin2hex($test3) === "d0b0646d696e" ? "YES ✓" : "NO ✗") . "\n";
$blocked3 = preg_match('#[\x00-\x1F\x7F\s]#u', $test3);
echo "Status: " . ($blocked3 ? "BLOCKED ✓" : "VULNERABLE ✗") . "\n\n";
// Test 4: Ideographic Space (should be blocked)
echo "[TEST 4] Ideographic Space (U+3000) - Control\n";
echo "----------------------------------------\n";
$test4 = "admin" . "\xE3\x80\x80" . "test";
echo "Payload hex: " . bin2hex($test4) . "\n";
echo "Expected: 61646d696ee3808074657374\n";
echo "Match: " . (bin2hex($test4) === "61646d696ee3808074657374" ? "YES ✓" : "NO ✗") . "\n";
$blocked4 = preg_match('#[\x00-\x1F\x7F\s]#u', $test4);
echo "Status: " . ($blocked4 ? "BLOCKED ✓" : "VULNERABLE ✗") . "\n\n";
// Summary
echo "========================================\n";
echo "SUMMARY\n";
echo "========================================\n";
$vuln_count = (!$blocked1 ? 1 : 0) + (!$blocked2 ? 1 : 0) + (!$blocked3 ? 1 : 0);
echo "Vulnerabilities found: $vuln_count/3\n";
echo "Patch effectiveness: " . ((3 - $vuln_count) / 3 * 100) . "%\n\n";
if ($vuln_count > 0) {
echo " CRITICAL: Patch is INSUFFICIENT!\n";
echo "Working exploits:\n";
if (!$blocked1) echo " • Zero-Width Space\n";
if (!$blocked2) echo " • RTL Override\n";
if (!$blocked3) echo " • Cyrillic Homograph\n";
} else {
echo "✓ All exploits blocked\n";
}
echo "\n========================================\n";
?>
Recommended Fix
Replace the current blacklist pattern with a whitelist approach:
// Current (VULNERABLE):
if (preg_match('#[\x00-\x1F\x7F\s]#u', $this->request['login'])) {
$this->aErrors = [$GLOBALS['strInvalidUsername']];
}
// Recommended (SECURE):
if (empty($this->request['login']) ||
strlen($this->request['login']) > 255 ||
!preg_match('/^[a-zA-Z0-9._@-]+$/D', $this->request['login']) ||
$this->request['login'] !== trim($this->request['login'])) {
$this->aErrors = [$GLOBALS['strInvalidUsername']];
}
Additional recommendations:
- Unicode normalization (NFC) before validation
- Implement confusables detection
- Log suspicious username patterns
- Display hex representation in admin UI
Verification Steps for Developers
- Save the test script above as
test_vulnerability.php - Run:
php test_vulnerability.php - Observe output - you should see 3 VULNERABLE results
- Apply the recommended fix
- Run the test again - all should show BLOCKED
POC:
{F5026461}
References
- Unicode Security: https://www.unicode.org/reports/tr36/
- CWE-20: https://cwe.mitre.org/data/definitions/20.html
- OWASP Input Validation: https://cheatsheetseries.owasp.org/
Contact
Please acknowledge receipt of this report and provide an estimated timeline for patch development and CVE Assignment [kassem_s94] https://x.com/kassem_s94 https://t.me/apesofficial https://hackerone.com/kassem_s94?type=user
Impact
- MOST DANGEROUS - Visually indistinguishable from "admin"
- Perfect phishing vector
- Users cannot detect the fake account
- Credential harvesting
- Admin impersonation attacks