Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Device registration] Leftover bytes detected while parsing authenticator data #440

Closed
AntonyChiossi opened this issue Sep 18, 2023 · 7 comments · Fixed by #441
Closed

Comments

@AntonyChiossi
Copy link

Describe the issue

When using Firefox (version 117), I encounter the error message "Leftover bytes detected while parsing authenticator data," but this issue is not replicated in Chrome—where the functionality works as expected. I am seeking assistance in understanding the cause of this discrepancy and finding a solution to ensure consistent behavior across browsers.

Reproduction Steps

  1. I was able to reproduce it only locally, is there some demo project with the latest version where I can test it?

Expected behavior

Be able to register a Fido2 device

Code Samples + WebAuthn Options and Responses

{
  "conf": {
    "registrationRequest": {
      "challenge": "XXXXXXXXX",
      "rp": {
        "name": "XXXXX",
        "id": "localhost"
      },
      "user": {
        "id": "XXXX",
        "name": "XXXX",
        "displayName": "XXXX"
      },
      "pubKeyCredParams": [
        {
          "alg": -8,
          "type": "public-key"
        },
        {
          "alg": -7,
          "type": "public-key"
        },
        {
          "alg": -257,
          "type": "public-key"
        }
      ],
      "timeout": 60000,
      "attestation": "indirect",
      "excludeCredentials": [],
      "authenticatorSelection": {
        "residentKey": "preferred",
        "userVerification": "preferred",
        "requireResidentKey": false
      },
      "extensions": {
        "credProps": true
      }
    }
  }
}

Dependencies

Both browser and server packages are at latest versions.

  • @simplewebauthn/browser@8.0.2
  • @simplewebauthn/server@8.1.1

SimpleWebAuthn Libraries

  • browser
    ├── @simplewebauthn/browser@8.0.2
    ├── @simplewebauthn/typescript-types@4.0.0
  • server
    @simplewebauthn/server@8.1.1 overridden

Additional context

I tried commenting out this code:

// if (authData.byteLength > pointer) {
//     throw new Error('Leftover bytes detected while parsing authenticator data');
// } 

And the next error encountered was:

if (fidoUserVerification === 'required') {
            // Require `flags.uv` be true (implies `flags.up` is true)
    if (!flags.uv) {
        throw new Error('User verification required, but user could not be verified');
    }
}
@CleyFaye
Copy link

CleyFaye commented Sep 21, 2023

Can you try to manually provide a list of algorithms and only keep -7 and -257 ?
This is in the parameter for generateRegistrationOptions():

{
  supportedAlgorithmIDs: [-7, -257],
}

We also noticed a similar behavior (invalid length of the auth data response in firefox) but only when the algorithm identified by -8 was used. It may help to narrow the issue.

@Geam
Copy link

Geam commented Sep 21, 2023

I have the same "Leftover bytes detected" issue and as far as I understand, it seems to be related to bad publicKey cbor, the cbor start with a3 instead of a4 which makes the isoCBOR.decodeFirst function return truncated data leaving the public key out.

Here's my actual data

{
  "id": "ctOho_p88y9ENn34R1hf8IUMe9YsM4q0W-H9pv23mYL5bCDvwLtu2TR-jB53aQ5nsiW0haCY9vRv3j8qhazQF3oE1rtcdWb7iYgd_kjqerw2H3rK-GpZZq3vVXkw-lwEXGNvUM-TjlCKgbhFE06ymI3Drwq2-Yz8YVUyaEtKY2M",
  "rawId": "ctOho_p88y9ENn34R1hf8IUMe9YsM4q0W-H9pv23mYL5bCDvwLtu2TR-jB53aQ5nsiW0haCY9vRv3j8qhazQF3oE1rtcdWb7iYgd_kjqerw2H3rK-GpZZq3vVXkw-lwEXGNvUM-TjlCKgbhFE06ymI3Drwq2-Yz8YVUyaEtKY2M",
  "response": {
    "attestationObject": "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVkBBrQEmbAnGmiVcmfeTsQAVqdMh1jGWC4eAfzzV9cxAee6RQAAAAQAAAAAAAAAAAAAAAAAAAAAAIBy06Gj-nzzL0Q2ffhHWF_whQx71iwzirRb4f2m_beZgvlsIO_Au27ZNH6MHndpDmeyJbSFoJj29G_ePyqFrNAXegTWu1x1ZvuJiB3-SOp6vDYfesr4allmre9VeTD6XARcY29Qz5OOUIqBuEUTTrKYjcOvCrb5jPxhVTJoS0pjY6MBY09LUAMnIGdFZDI1NTE5IZggGNUYWBhzGOYYiRjrGKsYfhj9GP0YXRhLCBhLGHMY6BjhGPgYxxUY_xj1GDoY_RijGGsYXxEJGD4YOxQ",
    "clientDataJSON": "eyJjaGFsbGVuZ2UiOiJXd0hTZ2pibFJRbXZnZmowUV9EZ3p2a0NBRlFYRzVEVGszcE9SZEZ2cUVFIiwib3JpZ2luIjoiaHR0cHM6Ly9lZHdpbi5jbGllbnRzLmJldGEua2VlZXgubWUiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0"
  },
  "type": "public-key",
  "clientExtensionResults": {}
}

Here's the decoded public key I got with original data

Map(3) {
  1 => 'OKP', // kty
  3 => -8, // alg
  -1 => 'Ed25519' // crv
}

If I change the byte to a4, here's what I got

Map(4) {
  1 => 'OKP', // kty
  3 => -8, // alg
  -1 => 'Ed25519', // crv
  -2 => [
    213,  88, 115, 230, 137, 235, 171, 126,
    253, 253,  93,  75,   8,  75, 115, 232,
    225, 248, 199,  21, 255, 245,  58, 253,
    163, 107,  95,  17,   9,  62,  59,  20
  ]
}

Which seems better. Though I'm not sure as to why kty and crv are strings instead of respectively 1 and 6.

@MasterKale
Copy link
Owner

MasterKale commented Sep 21, 2023

Which seems better. Though I'm not sure as to why kty and crv are strings instead of respectively 1 and 6.

Ah, it seems this issue I resolved over in the py_webauthn project has finally found its way to SimpleWebAuthn:

duo-labs/py_webauthn#160

There's a follow-up issue that tracks this down to an issue with Firefox:

duo-labs/py_webauthn#175

Are you using Firefox 117 by chance?

@Geam
Copy link

Geam commented Sep 21, 2023

Thank you for the reply.
Yes, I'm using firefox 117.0.1

@MasterKale
Copy link
Owner

This is fixed in the newly published @simplewebauthn/server@8.2.0 ✌️

@AntonyChiossi
Copy link
Author

AntonyChiossi commented Oct 6, 2023

@MasterKale

After updating both packages to their latest version, registration fails but with a different error this time. Chrome keeps working.

Here some debugging info:

Working with Chrome:

{
  request: {
     challenge: 'NkUgPU8KfTEuMF-78rbkr81NIF0SoU9hBhkFRffApI0',
     rp: { name: 'REDACTED', id: 'localhost' },
     user: {
       id: 'REDACTED',
       name: 'REDACTED',
       displayName: 'REDACTED'
     },
     pubKeyCredParams: [ [Object], [Object], [Object] ],
     timeout: 60000,
     attestation: 'indirect',
     excludeCredentials: [],
     authenticatorSelection: {
       residentKey: 'preferred',
       userVerification: 'preferred',
       requireResidentKey: false
     },
     extensions: { credProps: true }
   },
   response: {
     id: 'KEthTlOv7trIQ0g9hvZmvAOxVOmhh-UPa7QotW5nNDUNsJXdIviXylbk5HvEhtfx',
     rawId: 'KEthTlOv7trIQ0g9hvZmvAOxVOmhh-UPa7QotW5nNDUNsJXdIviXylbk5HvEhtfx',
     response: {
       attestationObject: 'o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEYwRAIgaDfm9cLN7bE8fIIT2JwNNjpggnHXClnAiBNZ3WYrNBMCICoDf7lc6Y3eX70TNVWyYTy75BdmPPSmN88lcfQ97eAzY3g1Y4FZAt0wggLZMIIBwaADAgECAgkA4RPwzmmndbYwDQYJKoZIhvcNAQELBQAwLjEsMCoGA1UEAxMjWXViaWNvIFUyRiBSb290IENBIFNlcmlhbCA0NTcyMDA2MzEwIBcNMTQwODAxMDAwMDAwWhgPMjA1MDA5MDQwMDAwMDBaMG8xCzAJBgNVBAYTAlNFMRIwEAYDVQQKDAlZdWJpY28gQUIxIjAgBgNVBAsMGUF1dGhlbnRpY2F0b3IgQXR0ZXN0YXRpb24xKDAmBgNVBAMMH1l1YmljbyBVMkYgRUUgU2VyaWFsIDEzMjQzNTY1NzcwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS-EvB5JATjjS2-GSN4diiQ48S8kAj5g26rCBkDfZIcQYjKL6qE6gKM39rgzxD1khkn6i1A40ik2wC_8Z_60--qo4GBMH8wEwYKKwYBBAGCxAoNAQQFBAMFBAMwIgYJKwYBBAGCxAoCBBUxLjMuNi4xLjQuMS40MTQ4Mi4xLjEwEwYLKwYBBAGC5RwCAQEEBAMCBDAwIQYLKwYBBAGC5RwBAQQEEgQQpOn8bUy-R1i4ujdZi7W7qjAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQChRXSOMBqLK8u9kS4S3r2Ma7Dz740fXnifG3l8Il57IXCDLH9r3qXAG9-a8cBVTF4MvGOBMK90wB1B8LXlCUM6lRM2sKDYN2c1AxhYB3T4EEmVuxT9dDwumyOOm68aOi2nnGDKtgxelx-71dj-bKvZGN3ToOysx8WKbsnxHnDo1qNOTxyxeEgKKG_AXjxLIAgZHTXaYTrY_h6uGVr96lPzKGD-Im7lVsdWE9Bce7xzRoO62faYWC71xbBiNWU-t53v8QBDi_Ua4zYR0Zm_ULnwRUqHQ4X5MPLzxRw59NBh3JUuVKWC69ByxFqIOlFm56Y_UuLvYo8E3Q_wsPBj1WBraGF1dGhEYXRhWJ9Jlg3liA6MaHQ0Fw9kdmBbj-SuuaKGMseZXPO6gx2XY8UAAAAEpOn8bUy-R1i4ujdZi7W7qgAwKEthTlOv7trIQ0g9hvZmvAOxVOmhh-UPa7QotW5nNDUNsJXdIviXylbk5HvEhtfxpAEBAycgBiFYIChLYU5Tr-7ayENIPYac8k9s8ypXjiqCFkDg_FpuygxpoWtjcmVkUHJvdGVjdAI',
       clientDataJSON: 'eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiNVFVQml0NjRiZFViQ21faGtFSWN1ZnJkNDY3VVhidjdXa1U3VW5xYlM5OCIsIm9yaWdpbiI6Imh0dHBzOi8vbG9jYWxob3N0OjQyMDAiLCJjcm9zc09yaWdpbiI6ZmFsc2V9',
       transports: [Array],
       publicKeyAlgorithm: -8,
       publicKey: 'MCowBQYDK2VwAyEAKEthTlOv7trIQ0g9hpzyT2zzKleOKoIWQOD8Wm7KDGk',
       authenticatorData: 'SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2PFAAAABKTp_G1MvkdYuLo3WYu1u6oAMChLYU5Tr-7ayENIPYb2ZrwDsVTpoYflD2u0KLVuZzQ1DbCV3SL4l8pW5OR7xIbX8aQBAQMnIAYhWCAoS2FOU6_u2shDSD2GnPJPbPMqV44qghZA4PxabsoMaaFrY3JlZFByb3RlY3QC'
     },
     type: 'public-key',
     clientExtensionResults: { credProps: [Object] },
     authenticatorAttachment: 'cross-platform'
   },
   expectedChallenge: '5QUBit64bdUbCm_hkEIcufrd467UXbv7WkU7UnqbS98',
   expectedOrigin: 'https://localhost:4200',
   expectedRPID: 'localhost',
   verification: {
     verified: true,
     registrationInfo: {
       fmt: 'packed',
       counter: 4,
       aaguid: 'a4e9fc6d-4cbe-4758-b8ba-37598bb5bbaa',
       credentialID: [Uint8Array],
       credentialPublicKey: [Uint8Array],
       credentialType: 'public-key',
       attestationObject: [Uint8Array],
       userVerified: true,
       credentialDeviceType: 'singleDevice',
       credentialBackedUp: false,
       origin: 'https://localhost:4200',
       rpID: 'localhost',
       authenticatorExtensionResults: [Object]
     }
   }
 }

Failing with Firefox

{
  request: {
     challenge: 'OqmoL2yMQdmwcL4jLL85SkcEq1_6cI0InUDUcO1WE1o',
     rp: { name: 'REDACTED', id: 'localhost' },
     user: {
       id: '63d3d082b7610778c308f25c',
       name: 'REDACTED',
       displayName: 'REDACTED'
     },
     pubKeyCredParams: [ [Object], [Object], [Object] ],
     timeout: 60000,
     attestation: 'indirect',
     excludeCredentials: [],
     authenticatorSelection: {
       residentKey: 'preferred',
       userVerification: 'preferred',
       requireResidentKey: false
     },
     extensions: { credProps: true }
   },
   response: {
     id: '2PvlO37W-pdWdMvEnigOU0BlBZ-PtE4OZSZsxPbRN8bodRw378VPVmaur1Oks6u5',
     rawId: '2PvlO37W-pdWdMvEnigOU0BlBZ-PtE4OZSZsxPbRN8bodRw378VPVmaur1Oks6u5',
     response: {
       attestationObject: 'o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEYwRAIgHcyLYtm1V14B1Y90sNTpZGXpi2OV40za0-8xkyYtTeECICkGdaW-oRAJHrkbUuEetcGVgRXxGXHtAbkZt2fTKS2kY3g1Y4FZAt0wggLZMIIBwaADAgECAgkA4RPwzmmndbYwDQYJKoZIhvcNAQELBQAwLjEsMCoGA1UEAxMjWXViaWNvIFUyRiBSb290IENBIFNlcmlhbCA0NTcyMDA2MzEwIBcNMTQwODAxMDAwMDAwWhgPMjA1MDA5MDQwMDAwMDBaMG8xCzAJBgNVBAYTAlNFMRIwEAYDVQQKDAlZdWJpY28gQUIxIjAgBgNVBAsMGUF1dGhlbnRpY2F0b3IgQXR0ZXN0YXRpb24xKDAmBgNVBAMMH1l1YmljbyBVMkYgRUUgU2VyaWFsIDEzMjQzNTY1NzcwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS-EvB5JATjjS2-GSN4diiQ48S8kAj5g26rCBkDfZIcQYjKL6qE6gKM39rgzxD1khkn6i1A40ik2wC_8Z_60--qo4GBMH8wEwYKKwYBBAGCxAoNAQQFBAMFBAMwIgYJKwYBBAGCxAoCBBUxLjMuNi4xLjQuMS40MTQ4Mi4xLjEwEwYLKwYBBAGC5RwCAQEEBAMCBDAwIQYLKwYBBAGC5RwBAQQEEgQQpOn8bUy-R1i4ujdZi7W7qjAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQChRXSOMBqLK8u9kS4S3r2Ma7Dz740fXnifG3l8Il57IXCDLH9r3qXAG9-a8cBVTF4MvGOBMK90wB1B8LXlCUM6lRM2sKDYN2c1AxhYB3T4EEmVuxT9dDwumyOOm68aOi2nnGDKtgxelx-71dj-bKvZGN3ToOysx8WKbsnxHnDo1qNOTxyxeEgKKG_AXjxLIAgZHTXaYTrY_h6uGVr96lPzKGD-Im7lVsdWE9Bce7xzRoO62faYWC71xbBiNWU-t53v8QBDi_Ua4zYR0Zm_ULnwRUqHQ4X5MPLzxRw59NBh3JUuVKWC69ByxFqIOlFm56Y_UuLvYo8E3Q_wsPBj1WBraGF1dGhEYXRhWLlJlg3liA6MaHQ0Fw9kdmBbj-SuuaKGMseZXPO6gx2XY0UAAAAEpOn8bUy-R1i4ujdZi7W7qgAw2PvlO37W-pdWdMvEnigOU0BlBZ-PtE4OZSZsxPbRN8bodRw378VPVmaur1Oks6u5owFjT0tQAycgZ0VkMjU1MTkhmCAY2Bj7GOUYOxh-GNYY-hiXGFYYdBjLGMQYnhjCGJYYuRjrGF8Yvhh0GB0YkhhHDhg3GE4YewcYORhPGNAY6A',
       clientDataJSON: 'eyJjaGFsbGVuZ2UiOiJEVHlCRUxQWEx5WHIwZlQ1ZmttaGlzbF9BRU1jMTNld1FUUVMteExDdkNRIiwib3JpZ2luIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDIwMCIsInR5cGUiOiJ3ZWJhdXRobi5jcmVhdGUifQ'
     },
     type: 'public-key',
     clientExtensionResults: {}
   },
   expectedChallenge: 'DTyBELPXLyXr0fT5fkmhisl_AEMc13ewQTQS-xLCvCQ',
   expectedOrigin: 'https://localhost:4200',
   expectedRPID: 'localhost',
   verification: { verified: false }
 }

The verification key is the result of the method verifyRegistrationResponse

@MasterKale
Copy link
Owner

After updating both packages to their latest version, registration fails but with a different error this time. Chrome keeps working.

@AntonyChiossi This is a separate issue, please create a new issue. I did some digging and it doesn't seem related to Firefox because that's a "packed" attestation statement in there which means signature verification is failing in a way that's related to the public key in the leaf cert, not the one provided in authData.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants