Passkey Editor: A Burp Suite Extension for Attacking WebAuthn

mooreds1 pts0 comments

Passkey Editor: a Burp Suite Extension for Attacking WebAuthn - Anvil Secure

By Anvil SecureOn August 10, 20260 Comments

By Matteo Giordano

This tool, Passkey Editor, comes out of the same work as the Demystifying Passkeys Under the Hood series: The Protocol (ceremonies at the byte level), The Architecture, and Under Attack (the attack classes that survive a correct ceremony, coming soon).

TL;DR

WebAuthn traffic is a wall of opaque bytes. The fields you want to reach are buried in CBOR (Concise Binary Object Representation), and the CBOR is usually buried under one or two layers of Base64 before it reaches the wire, making it very hard to manually run all the checks you actually want to run.

Passkey Editor is a Burp extension that detects a registration or authentication ceremony, unwraps the encoding chain, decodes the CBOR into a dedicated tab across Proxy and Repeater (editable wherever the request is still in flight), and drives the routine ceremony-layer attacks from an "Attacks" dropdown.

The code is at github.com/anvilsecure/passkey-editor.

Why I built it

The first time I tried to test a passkey flow on a real engagement, I got maybe ten minutes in and stopped. You proxy the login, you find the POST carrying the assertion, and then there's nothing to work with. The body is essentially a blob and Burp's decoders get you partway: clientDataJSON unwraps to readable JSON you can tamper with in the Inspector. However, the fields that are crucial for the ceremony don't unwrap so easily: authData and the attestation object come back as CBOR, which nothing in Burp will read or edit , so past that layer, you're fuzzing blind .

What I wanted was what the JWT Editor family did for JSON Web Tokens: a tab that shows up on the interesting request, decodes it into something you can change, and puts it back on the wire in a form the server still accepts. I wasn't satisfied with what was out there, so I started building my own.

The problem: WebAuthn is opaque over the wire

Let me be specific about why passkey traffic resists Burp.

A WebAuthn ceremony doesn't ship clean and undecoded JSON. The authenticator data, the attestation object, and the public key are CBOR , a binary serialization Burp has no native view for. That alone would be manageable, but the complication is that relying parties (RPs) almost never put raw CBOR on the wire. They Base64-encode it first, often twice , mixing url-safe and standard alphabets and padded and unpadded variants in the same request, and some wrap the result in a JSON envelope with their own field names.

So there's no single format to target ... everybody rolled their own, and ideally you'll need to unwrap each one of them.

Here's the same ceremony as three real deployments send it: (1) Microsoft explodes the WebAuthn response into flat form parameters, (2) GitHub keeps the spec's field names but nests them in JSON inside a multipart body, and (3) Google hides the identical fields inside a stringified positional array in its batchexecute remote procedure call (RPC) endpoint, with no field names at all, just indexes, then URL-encodes the whole thing. Three encodings that share almost nothing, carrying the same fields.

The same fields, wrapped in three incompatible ways.

I walked through the byte-level structure of all of this in Part 1 of the series: the authData layout, the flags byte, the rpIdHash, clientDataJSON and its origin binding, so I won't repeat it here.

The point for tooling is that by the time you've peeled the wrappers and parsed the CBOR by hand, the ceremony is over and the challenge you meant to tamper with has likely expired .

Here's a registration body straight off the wire, in one of the plenty of ways it can come to you.

"username": "demo_user",<br>"response": {<br>"id": "SZNyIn7tWd5VQQryYcmtZpBSzA31paGNkqwz-yHSFtM",<br>"rawId": "SZNyIn7tWd5VQQryYcmtZpBSzA31paGNkqwz-yHSFtM",<br>"response": {<br>"attestationObject": "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YViBdKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvBFAAAAAQECAwQFBgcIAQIDBAUGBwgAIEmTciJ-7VneVUEK8mHJrWaQUswN9aWhjZKsM_sh0hbTpAEBAycgBiFYIENoOm9EGQHj8Y76oGP56jdEtLCtep-dA8fPwc9oWZvH",<br>"clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoidmpSeGJHbC16MG11N2FpRFNROGRtT3dBcEQzLWRpUHRURDFjN2ZvRkdYMlNBZk5HZVJhclZyZnMyT2hZVkhtUEI0NFJ5YjEzMEZIMUhrV2tiZ2hPQ0EiLCJvcmlnaW4iOiJodHRwczovL3dlYmF1dGhuLmlvIiwiY3Jvc3NPcmlnaW4iOmZhbHNlLCJvdGhlcl9rZXlzX2Nhbl9iZV9hZGRlZF9oZXJlIjoiZG8gbm90IGNvbXBhcmUgY2xpZW50RGF0YUpTT04gYWdhaW5zdCBhIHRlbXBsYXRlLiBTZWUgaHR0cHM6Ly9nb28uZ2wveWFiUGV4In0",<br>"transports": ["internal"],<br>"publicKeyAlgorithm": -8,<br>"publicKey": "MCowBQYDK2VwAyEAQ2g6b0QZAePxjvqgY_nqN0S0sK16n50Dx8_Bz2hZm8c",<br>"authenticatorData": "dKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvBFAAAAAQECAwQFBgcIAQIDBAUGBwgAIEmTciJ-7VneVUEK8mHJrWaQUswN9aWhjZKsM_sh0hbTpAEBAycgBiFYIENoOm9EGQHj8Y76oGP56jdEtLCtep-dA8fPwc9oWZvH"<br>},<br>"type": "public-key",<br>"clientExtensionResults": { "credProps": { "rk": true } },<br>"authenticatorAttachment":...

passkey burp ceremony cbor editor webauthn

Related Articles