TL;DR;
This post explains a phishing technique for FIDO cross‑device (hybrid) authentication. An attacker can run an AitM proxy that shows a fake, OS‑like QR code prompt in the browser. The attack requires placing one or more Bluetooth beacons within the victim’s Bluetooth range. See Proof of Concept and Demo Video
Housekeeping
First of all, I want to make clear that I am 100% convinced of FIDO. That’s a game-changer when it comes to security! I recommend everyone start integrating FIDO either into their products or using it as authentication method for their workforce! My mission is to look at potential attack scenarios and raise awareness which leads hopefully to discussion that results in improvements to the overall ecosystem.
Another clarification up front to avoid any potential misunderstandings. This works ONLY if attacker has placed device(s) in BLE range (~150m) near the victim(s). From my point of view that is a valid attack scenario, think campuses, offices, airports, events, etc. The attacker only needs to place devices in physical proximity in public spaces, without personal contact. They probably don’t need access to any private or restricted areas.
Simlified Fido authentication with hybrid (caBLE) Flow
Before we dive into the abuse case, let’s look at the normal flow.
A user on a desktop opens a browser and wants to authenticate with FIDO on the website original.com
.
The relying party calls the JavaScript method navigator.credentials.get
, which is implemented by the browser as defined in the webAuthN spec. The browser displays a dialog where the user can choose how they want to authenticate. In that dialog, they can select options such as using a passkey on the device itself or a security key via USB or NFC. In our scenario, the user chooses the hybrid flow because they have a passkey on their mobile device but not on their desktop. It’s important to note that the dialog will only launch if the parameters passed by the relying party to navigator.credentials.get
match the origin of the website, in this case, original.com
.
Let’s look at the simplified steps when the hybrid flow is used. For example, we’ll use Windows 11 as the desktop and Android as the mobile device. The user has the authenticator app installed on their Android phone, with a device‑bound passkey registered for original.com
. When FIDO authentication starts, the browser opens the Windows Hello dialog.
1. User scans QR code (generated by Windows Hello)
As soon as the user selects the hybrid option, labeled iPhone, iPad, or Android device
, in the Windows Hello dialog, it generates a QR code, which the user scans with their Android device.
With that QR code, the Android device receives a secret (for later reference, Secret A).
2. Desktop checks proximity with BLE
Once the QR code is scanned, the Android device starts sending a Bluetooth (BLE) advertisement, which can be received by anyone within Bluetooth range.
The Windows Hello dialog on the desktop immediately starts scanning for those BLE advertisements after generating the QR code.
By reading the correct BLE advertisement, the Windows Hello dialog on the desktop also receives a secret (for later reference, Secret B).
3. Secure connection is established using exchanged secrets
Because the secrets were exchanged, a secure connection is established between the Windows Hello dialog on the desktop and the Android device via HTTP through a rendezvous server on the internet.
After the connection is established, the Windows Hello dialog on the desktop asks the Android device to perform a FIDO authentication for the origin original.com
.
4. User authenticates on mobile, then Desktop is authenticated
On the Android device, the user is prompted for FIDO authentication. They then provide either a PIN or biometrics, and the authentication response is sent to the Windows Hello dialog on the desktop. This response is, in turn, handed back to the browser, and the browser returns it as the result of the original call to navigator.credentials.get
.
Phishing Fido authentication with hybrid (caBLE) Flow
For this attack to work, I wrote two components available in the PoC on GitHub:
Server
, which is responsible for connecting to the device (in this example the Android device)Beacon
, which is responsible for listenting to BLE advertisements and forwarding them to theServer
But now let’s look at how the attack actually works:
The user opens a phishing link provided by an AitM proxy, e.g., Evilginx. This link opens phish.com
, and Evilginx proxies all requests to original.com
.
With Evilginx, the attacker can inject arbitrary JavaScript into the phishing site.
In this case, we inject JavaScript that hijacks the navigator.credentials.get
method and overrides it with our custom code. The following logic is implemented:
Once navigator.credentials.get
is executed by the website, we create a popup (using HTML elements) that looks exactly like the normal Windows Hello dialog.
The user cannot see any difference (except that the HTML dialog cannot be moved outside the browser window). In this fake Windows Hello dialog, we render only a single option: iPhone, iPad, or Android device
.
This effectively downgrades the user to the hybrid flow, even if they have other FIDO authenticators available.
1. User scans QR code (generated by attacker)
As soon as the user selects the hybrid option, labeled iPhone, iPad, or Android device
, in the fake Windows Hello dialog, the Server
generates a QR code, which the user scans with their Android device.
With that QR code, the Android device receives a secret (for later reference, Secret A).
2. Attacker receives proximity signal from one or more beacons
Once the QR code is scanned, the Android device starts sending a Bluetooth (BLE) advertisement, which can be received by anyone within Bluetooth range.
In this case, the attacker has placed several Beacon
’s around the area in advance where the user is located (e.g., an office location).
All deployed beacons forward the recognized BLE advertisements to the Server
.
Once the Server
receives the correct BLE advertisement, it is in possession of the secret provided by the Android device (for later reference, Secret B).
3. Secure connection is established using exchanged secrets
Because the secrets were exchanged, a secure connection is established between the Server and the Android device via HTTP through a rendezvous server on the internet.
After the connection is established, the Server asks the Android device to perform a FIDO authentication for the origin original.com
. Yes, original.com
, not phish.com
. It’s completely up to the Server
which messages it sends to the Android device. This is outside the browser, where no same-origin policy is enforced.
4. User authenticates on mobile, then attacker gains the session
On the Android device, the user is prompted for FIDO authentication. They then provide either a PIN or biometrics, and the authentication response is sent back to the Server
. It is then returned as the result of the original call to navigator.credentials.get
, which we have overridden with our custom logic.
Finally, Evilginx forwards the authentication response to original.com
, which returns a session after successful user authentication. The issued session is captured by Evilginx and is now known to the attacker.
Proof of Concept
I built a proof‑of‑concept (PoC) to demonstrate the attack and published the code on GitHub. The repository includes the Server
and Beacon
as components, along with instructions to run the demo end‑to‑end using the Evilgnix. You can find it here: https://github.com/denniskniep/fido-cross-device-phishing. Furthermore it contains a Demo Video.
Security Keys also affected
After scanning the QR code, the user can also complete authentication with a security key connected to the mobile device. I tested this with a USB‑connected security key on an Android phone.
No detection mechanism or opt-out available
At the moment, there is no way for a relying party to detect whether the hybrid flow was used, nor is there a supported mechanism to block it. It’s completely up to the user to decide whether to use the hybrid flow or not. Therefore the risk can not be controlled by the relying party.
Further improvements
OS Detection
The PoC currently covers Windows Hello on Windows 11. Extending it to other Windows versions and operating systems should be straightforward, as the core hybrid flow is the same. It would mainly require modeling the platform‑specific dialogs. Building HTML “evil twin” prompts that spoof the original UI.
Mobile App
The logic that listens for Bluetooth Low Energy (BLE) advertisements could also be built into a mobile application. If such an app achieves broad distribution, it could passively collect nearby signals and relay them to the server, reducing the need for dedicated beacons while expanding coverage.