In late October 2026, researchers at Abraxas Labs disclosed a high-severity vulnerability in phpMyAdmin 5.2.3, in its WebAuthn two-factor authentication. The first reports described a critical bypass that lets attackers skip hardware security key requirements entirely. Further analysis narrowed that picture. The flaw is not in the main phpMyAdmin codebase. It sits in a custom fallback implementation that only runs under certain conditions.
The difference between the library-backed authentication path and the internal fallback shows two recurring problems in application security: silent downgrades, and the gap between structural validation and cryptographic verification. To judge the real risk, you need to understand how WebAuthn works, what the vulnerable PHP class does, and which dependency setups decide the code path in production.
How WebAuthn authentication works
WebAuthn was developed by the W3C and the FIDO Alliance to avoid sending shared secrets during authentication. Passwords and TOTP both rely on a secret the server and client have in common. WebAuthn uses public-key cryptography instead.
During registration, the authenticator generates a key pair. The authenticator can be a hardware security key, a platform authenticator like TouchID, or a synced passkey. The private key stays inside the authenticator’s hardware or secure enclave. The public key goes to the relying party, which here is the phpMyAdmin server, and gets tied to the user’s account.
At login, the server sends a random challenge. The authenticator signs a data structure containing that challenge plus contextual information, using the private key. The server then checks the signature against the stored public key. A valid signature proves the client holds the private key, and the key never leaves the device.
The flaw: phpMyAdmin skips the signature check
The bug has nothing to do with elliptic curve or RSA math, and nobody compromised an authenticator. It lives in the server-side logic that validates the assertion response.
A correct verifier builds the exact byte sequence that was signed and checks the signature against it with the registered public key. That sequence is the raw binary authenticatorData concatenated with the SHA-256 hash of the raw clientDataJSON bytes.
phpMyAdmin’s fallback, CustomServer::parseAndValidateAssertionResponse, does a lot of structural validation and then never performs that final check. It confirms that the assertion has a valid credential identifier, the expected challenge, the correct origin, and a well-formed authenticator data structure with the User Present flag set. It even confirms the signature field decodes from Base64. But it never passes those decoded bytes, along with the stored public key, to a verification function such as openssl_verify().
So the server accepts any syntactically valid assertion, whether or not the legitimate private key signed it. The second factor shrinks to a metadata check that anyone can forge.
What the vulnerable code validated, and why it looked secure
The checks that did run are worth a close look, because they made the code look rigorous. The authenticatorData field is a byte array with this layout:
📬 Stay Ahead of Cyber Threats
Get the latest cybersecurity news, critical vulnerabilities, threat intelligence, tutorials, and exclusive giveaways delivered straight to your inbox. No spam. Unsubscribe anytime.
Subscribe to the Newsletter →- a 32-byte
rpIdHash, the SHA-256 hash of the relying party identifier (usually the domain) - one flags byte, where the least significant bit is User Present (UP) and the third bit is User Verified (UV)
- a 4-byte big-endian signature counter, which helps relying parties detect cloned authenticators
The custom implementation parsed all of this correctly. It extracted the rpIdHash and compared it to the hash of the configured domain, and it confirmed the UP bit was set. It also parsed clientDataJSON and checked that type was webauthn.get, that challenge matched the session nonce, and that origin matched the server URL.
An attacker can build all of that by hand. Put the correct challenge, origin, and credential ID in the JSON. Generate a plausible 37-byte authenticatorData block with the right rpIdHash and the UP flag. Append a random Base64 string as the signature. Because the verification routine is never called, the forged assertion passes and the attacker gets full access to the database administration interface.
Why only some installs are vulnerable: the silent fallback
If this code is so broken, why did it survive testing, and why does it exist at all? The answer is in phpMyAdmin’s dependency architecture.
phpMyAdmin relies on the external web-auth/webauthn-lib package for the cryptographic work. That library is well maintained and tested against the W3C spec. But the project’s Composer configuration did not strictly require it for every installation method, especially development and source-tree deployments.
When phpMyAdmin initializes the WebAuthn server, it checks whether the library’s classes are autoloadable:
- Library present: the app instantiates
WebauthnLibServer, which performs full cryptographic verification and rejects the forged assertions from the proof of concept. - Library missing: the app quietly falls back to the internal
CustomServerclass.
A missing library is common in manual Git checkouts where nobody ran composer install, and in CI/CD pipelines that strip optional packages. The fallback was probably meant to give a degraded but working experience where Composer could not run. It shipped without the cryptographic rigor to do that safely, and the vulnerability only appears under those deployment conditions.
Who is affected by the phpMyAdmin 5.2.3 vulnerability
phpMyAdmin is everywhere in web hosting and often serves as the main database management interface, so the first disclosure caused real concern. Independent technical analysis then found that the official release archives and official Docker images bundle the required dependencies or resolve them during the build. Those installs use the secure WebauthnLibServer, and the proof-of-concept exploit fails against them because the library rejects invalid signatures.
The risk is concentrated in non-standard deployments:
- direct repository clones where
composer installwas skipped or run with the wrong flags - custom Docker builds that prune dependencies to shrink the image
- legacy hosting control panels that bundle phpMyAdmin with incomplete package management
On these systems, phpMyAdmin silently downgrades to the insecure implementation. Anyone who has or can guess the primary MySQL credentials can then get in without the hardware key.
This is a failure to fail closed. A security feature that loses a dependency should disable itself and warn the administrator. It should never slide into an insecure state without telling anyone.
Why you shouldn’t write your own WebAuthn verifier
The CustomServer flaw is a good argument against implementing cryptographic protocols from scratch. WebAuthn is a complex specification. It involves binary parsing, strict origin validation, challenge lifecycle management, and several signature algorithms, including ES256 (ECDSA with P-256 and SHA-256) and RS256 (RSASSA-PKCS1-v1_5 with SHA-256). Handling them correctly takes precise byte manipulation and an understanding of ASN.1 DER encoding for ECDSA signatures.
web-auth/webauthn-lib takes care of those details, including JSON normalization and extracting public keys from COSE (CBOR Object Signing and Encryption) formats. The internal reimplementation copied a subset of that functionality and missed the core security property. It validated the context of the login attempt (who, where, and when) and never validated its authenticity. Context without authenticity proves nothing. A signed challenge proves possession of the private key, while a well-formed JSON object proves only that the client knows the expected format.
The nine other phpMyAdmin 5.2.3 claims
Abraxas Labs also claimed nine additional vulnerabilities in phpMyAdmin 5.2.3. They range from SQL injection in the Designer and central columns features to CSRF weaknesses and server-side request forgery (SSRF) through retained installer directories.
These claims deserve investigation and independent verification, and they should be assessed separately from the WebAuthn issue. Multiple third parties have reproduced and analyzed the WebAuthn bypass, and it is a confirmed cryptographic failure in one specific code path. The other claims cover different attack surfaces: query construction, session token validation, and output encoding. Rolling them all into one story of total compromise is inaccurate and makes remediation harder.
For example, SQL injection in the Designer requires authenticated access to that feature and depends on the MySQL server’s privilege model and version. An SSRF through an installer directory is a configuration and access control problem. Deleting the setup directory after installation fixes it, and that step is often forgotten. Prioritize the confirmed WebAuthn bypass in affected environments, and treat the rest as potential risks that need code review and proof-of-concept work.
How to check if you’re vulnerable and fix it
Start by finding out which WebAuthn implementation your install loads. Inspect the dependency tree or check the filesystem for the external library:
bash
test -f vendor/web-auth/webauthn-lib/src/Server.php && echo "Secure library present" || echo "Vulnerable fallback likely active"
If the library is missing, you have two options. Install it with Composer and make sure all production dependencies resolve, or disable WebAuthn authentication in the phpMyAdmin configuration until you can patch or rebuild the environment.
Upgrading the version number in a custom build pipeline will not fix this if the pipeline still strips web-auth/webauthn-lib. Audit the build itself, and treat security-critical dependencies as mandatory requirements, not optional extras.
How to test WebAuthn implementations properly
A typical login unit test checks that valid credentials get in and invalid ones don’t. Testing WebAuthn takes more, because you need to tell a structurally valid but cryptographically invalid assertion apart from a genuine one. A proper regression suite for phpMyAdmin’s WebAuthn support should include:
- valid assertions generated with a test private key
- assertions with mismatched challenges
- assertions with incorrect origins
- assertions that are structurally perfect but signed with a completely different private key
That last case is the one that matters. A suite that only checks for malformed JSON or empty signatures will miss this bug. The tests must assert that CustomServer rejects a valid-looking assertion when signature verification fails.
The architecture needs a fix too. If the external library is required for secure operation, it should move from a suggested package to a hard requirement in the Composer configuration. The application should then throw a fatal exception at initialization if the library classes can’t be loaded, instead of quietly instantiating a vulnerable custom parser.
Key takeaways for defenders and developers
As more applications adopt passwordless login, passkeys, and other cryptographic protocols, the pull toward custom parsers and compatibility fallbacks will continue. This incident shows what that costs. Checking the metadata of a cryptographic payload gives no security guarantee when the signature check is missing.
- Fail closed. If a dependency is missing, the feature should become unavailable. Its security should never degrade quietly.
- Audit what actually runs. A secure codebase deployed with an incomplete dependency graph is as vulnerable as an insecure one. Verify the code that executes in production, not only the code in the repository.
- Test the negative cases. Include assertions that look perfect but carry the wrong signature.
- Separate the findings. Triage the confirmed WebAuthn bypass first and verify the other nine claims on their own evidence.









