TL;DR
I was credited as one of the reporters for CVE-2026-62263 in OpenAM.
The affected component was:
org.openidentityplatform.openam:openam-auth-webauthnThe issue was a Java deserialization bug in the WebAuthn authentication flow.
The previous fix for GHSA-6c99-87fr-6q7r wrapped WebAuthn authenticator deserialization in an ObjectInputFilter. That filter was intended to allow only AuthenticatorImpl.
The problem was the filter logic around serialization depth.
It allowed nested objects at stream depth greater than 1, so the allowlist only meaningfully constrained the root object. Everything deeper in the object graph was left unchecked.
The vulnerable shape
The advisory describes the filter behavior like this:
depth == 1 -> root concrete classdepth > 1 -> nested object graphThe filter allowed the nested graph too early.
In simplified form, the bug looked like this:
if (filterInfo.depth() > 1) { return ObjectInputFilter.Status.ALLOWED;}
if (filterInfo.serialClass() == AuthenticatorImpl.class) { return ObjectInputFilter.Status.ALLOWED;}
return ObjectInputFilter.Status.REJECTED;That policy is not a real allowlist for the full stream.
It only checks the root class properly.
An attacker can keep the root object as AuthenticatorImpl, then place a gadget chain inside the nested object graph. The filter accepts the nested classes because their depth is greater than 1.
Why the depth check matters
Java serialization filters are consulted for classes in the object graph, not only for the first object.
That means a deserialization filter has to make a decision for every class that appears in the stream.
If the filter says “allow everything below the root,” then a root allowlist does not protect the nested state.
For this bug, the attacker-controlled stream could be structured as:
AuthenticatorImpl└── nested object └── gadget chain object └── readObject / readResolve side effectThe cast to AuthenticatorImpl happens after deserialization.
The dangerous part is that gadget code can execute during readObject() or readResolve() before the application gets a chance to cast the object or verify the WebAuthn assertion.
Reachability
The advisory states that the sink is reachable before authentication through an attacker-chosen userHandle.
That is the important boundary.
The issue is not only “unsafe deserialization exists somewhere in code.” It is reachable from the WebAuthn authentication path before the attacker has an authenticated session.
The practical chain is:
attacker-controlled userHandle-> WebAuthn authenticator lookup / deserialization-> ObjectInputFilter checks root AuthenticatorImpl-> nested gadget graph is allowed by depth rule-> readObject() / readResolve() executes during deserializationRemote code execution depends on a usable gadget being present on the classpath, but the filter bug is what re-opens that path.
Relation to the earlier advisory
This bug is related to the earlier WebAuthn deserialization advisory:
GHSA-6c99-87fr-6q7rThe earlier fix added filtering around deserialization.
CVE-2026-62263 is about the filter being too shallow. It restricted the top-level object but did not enforce the same rule on the rest of the object graph.
That distinction matters because allowlisting a root type is not enough when the root object can carry attacker-controlled nested state.
Impact
The public advisory classifies this as:
- CWE:
CWE-502 - Severity:
High - Impact: remote code execution when a gadget is available on the classpath
The affected flow is pre-authentication WebAuthn processing.
The exploitability still depends on a compatible gadget chain, but the security boundary that was supposed to stop nested classes was not actually enforcing a nested-class allowlist.
Versions
The public advisory lists:
- CVE:
CVE-2026-62263 - GHSA:
GHSA-gf8h-gq53-288j - Package:
org.openidentityplatform.openam:openam-auth-webauthn - Severity:
High - CWE:
CWE-502 - Affected:
<= 16.1.1 - Patched:
16.1.2