Crypto-View

panva/node-oidc-provider

Readiness score
13 of 100
How this is calculated · previous scan 13
Cryptographic posture
Quantum-vulnerable 110 Already broken 34 Reduced margin 14 Could not be determined 86 Quantum-safe 59
To address149
Key establishment64
Inventory only1
Total findings304
What was analysed
Branch main
Commit 8a5917001cbee9d328f7854043d36ed8a03f360e chore(release): 9.12.2
Committed 2026-09-05 12:36 UTC
Scanned 2026-09-07 18:38 UTC 3 days ago
Coverage 444 files, 420 javascript

Earlier scans of this repository

13 scans · score 14 → 0 · compare any two
13 scans · 14 → 0 (down 14). The filled point is the scan you are reading.
Scanned Commit Score To address
3 hours ago d6691b1ef994 main 0 566 Compare
4 hours ago d6691b1ef994 main 9 128 Compare
18 hours ago 78474ace5fb2 9 123 Compare
20 hours ago 8a5917001cbe main 9 128 Compare
23 hours ago 8a5917001cbe main 9 128 Compare
1 day ago 8a5917001cbe main 9 128 Compare
1 day ago 8a5917001cbe main 9 128 Compare
1 day ago 8a5917001cbe main 9 128 Compare
3 days ago 8a5917001cbe main 13 149 Compare
3 days ago this scan 8a5917001cbe main 13 149
4 days ago 8a5917001cbe main 13 149 Compare
10 days ago 1ed7795bea6c main 13 149 Compare
11 days ago 78474ace5fb2 14 144 Compare

Every repository in this history is re-scanned weekly.

List of cryptographic assets

RSA-PKCS1v15 Already broken Recorded traffic 34 places See details

JWT signed with a classical algorithm

A JOSE `alg` value. RS*, PS*, ES* and EdDSA sign with a quantum-vulnerable key; HS* is an HMAC and is not affected. `alg: 'none'` is reported as a critical defect today.

This is already unsafe today, with no quantum computer involved. PKCS#1 v1.5 encryption padding is vulnerable to Bleichenbacher oracles today, and the underlying RSA is broken by Shor.

What to do. No standardised post-quantum JOSE algorithm exists yet. Keep token lifetimes short.

  1. lib/consts/client_attributes.js:32 authorization_signed_response_alg: 'RS256',
  2. lib/consts/client_attributes.js:36 id_token_signed_response_alg: 'RS256',
  3. lib/consts/client_attributes.js:37 introspection_signed_response_alg: 'RS256',
  4. lib/consts/dev_keystore.js:4 alg: 'RS256',
  5. lib/helpers/defaults.js:826 id_token_signed_response_alg: 'RS256',
  6. test/client_auth/client_auth.test.js:64 test path alg: 'RS256',
  7. test/client_auth/client_auth.test.js:1463 test path alg: 'RS256',
  8. test/client_auth/client_auth.test.js:1511 test path alg: 'RS256',
  9. test/client_auth/client_auth.test.js:1523 test path alg: 'RS256',
  10. test/client_auth/client_auth.test.js:1535 test path alg: 'RS256',
  11. test/client_auth/client_auth.test.js:1547 test path alg: 'RS256',
  12. test/client_auth/client_auth.test.js:1559 test path alg: 'RS256',
  13. test/client_auth/client_auth.test.js:1571 test path alg: 'RS256',
  14. test/client_auth/client_auth.test.js:1583 test path alg: 'RS256',
  15. test/client_auth/client_auth.test.js:1595 test path alg: 'RS256',
  16. test/client_auth/client_auth.test.js:1622 test path alg: 'RS256',
  17. test/configuration/client_metadata.test.js:1148 test path userinfo_signed_response_alg: 'RS256',
  18. test/configuration/client_metadata.test.js:1253 test path introspection_signed_response_alg: 'RS256',
  19. test/configuration/client_metadata.test.js:1353 test path authorization_signed_response_alg: 'RS256',
  20. test/configuration/client_metadata.test.js:2163 test path id_token_signed_response_alg: 'RS256',
  21. test/core/implicit/implicit.config.js:24 test path id_token_signed_response_alg: 'RS256',
  22. test/encryption/encryption.config.js:37 test path userinfo_signed_response_alg: 'RS256',
  23. test/external_signing/external_signing.config.js:111 test path id_token_signed_response_alg: 'RS256',
  24. test/formats/jwt.test.js:100 test path expect(header).to.have.property('kid', i(this.provider).keystore.selectForSign({ alg: 'RS256' })[0].kid);
  25. test/formats/jwt.test.js:116 test path expect(header).to.have.property('kid', i(this.provider).keystore.selectForSign({ alg: 'RS256' })[0].kid);
  26. test/formats/jwt.test.js:122 test path const [source] = keystore.selectForSign({ alg: 'RS256' });
  27. test/formats/jwt.test.js:133 test path sign: { alg: 'RS256', kid: jwk.kid },
  28. test/jwks/jwks-enc.config.js:30 test path alg: 'RS256',
  29. test/jwks/jwks-noenc.config.js:30 test path alg: 'RS256',
  30. test/jwks/jwks_uri.test.js:30 test path alg: 'RS256',
  31. test/jwks/jwks_uri.test.js:95 test path alg: 'RS256',
  32. test/jwt_introspection/jwt_introspection.config.js:18 test path introspection_signed_response_alg: 'RS256',
  33. test/registration_management/registration_management.test.js:102 test path const client = await setup.call(this, { userinfo_signed_response_alg: 'RS256' });
  34. test/registration_management/registration_management.test.js:130 test path const client = await setup.call(this, { userinfo_signed_response_alg: 'RS256' });
js.jwt.algorithm · CWE-327
ECDSA Quantum-vulnerable 36 places See details

JWT signed with a classical algorithm

A JOSE `alg` value. RS*, PS*, ES* and EdDSA sign with a quantum-vulnerable key; HS* is an HMAC and is not affected. `alg: 'none'` is reported as a critical defect today.

A quantum computer of sufficient size breaks this completely. It has to be replaced, not tuned. Broken by Shor's algorithm on a cryptographically relevant quantum computer.

What to do. No standardised post-quantum JOSE algorithm exists yet. Keep token lifetimes short.

  1. test/ciba/ciba.config.js:105 test path backchannel_authentication_request_signing_alg: 'ES256',
  2. test/ciba/ciba.test.js:946 test path }).setProtectedHeader({ alg: 'ES256' })
  3. test/ciba/ciba.test.js:972 test path }).setProtectedHeader({ alg: 'ES256' })
  4. test/ciba/ciba.test.js:1006 test path }).setProtectedHeader({ alg: 'ES256' })
  5. test/ciba/ciba.test.js:1040 test path }).setProtectedHeader({ alg: 'ES256' })
  6. test/ciba/ciba.test.js:1074 test path }).setProtectedHeader({ alg: 'ES256' })
  7. test/custom_grants/grant_implementations.test.js:94 test path .setProtectedHeader({ alg: 'ES256' })
  8. test/custom_grants/grant_implementations.test.js:170 test path alg: 'ES256',
  9. test/custom_grants/grant_implementations.test.js:225 test path { algorithms: ['ES256'], key: this.jwtKeyPair.publicKey },
  10. test/dpop/dpop.test.js:27 test path }).setProtectedHeader({ alg: 'ES256', typ: 'dpop+jwt', jwk: await exportJWK(keypair.publicKey) })
  11. test/dpop/dpop.test.js:123 test path alg: 'ES256',
  12. test/dpop/dpop.test.js:173 test path alg: 'ES256',
  13. test/dpop/dpop.test.js:197 test path alg: 'ES256',
  14. test/dpop/dpop.test.js:216 test path alg: 'ES256',
  15. test/dpop/dpop.test.js:232 test path .setProtectedHeader({ alg: 'ES256', typ: 'dpop+jwt', jwk: this.jwk })
  16. test/dpop/dpop.test.js:246 test path .setProtectedHeader({ alg: 'ES256', typ: 'dpop+jwt', jwk: this.jwk })
  17. test/dpop/dpop.test.js:261 test path .setProtectedHeader({ alg: 'ES256', typ: 'dpop+jwt', jwk: this.jwk })
  18. test/dpop/dpop.test.js:292 test path .setProtectedHeader({ alg: 'ES256', typ: 'dpop+jwt', jwk: this.jwk })
  19. test/external_signing/external_signing.config.js:103 test path id_token_signed_response_alg: 'ES256',
  20. test/external_signing/external_signing.config.js:119 test path id_token_signed_response_alg: 'ES384',
  21. test/fapi/fapi-final.test.js:115 test path }).setProtectedHeader({ alg: 'ES256' }).sign(keypair.privateKey);
  22. test/fapi/fapi-final.test.js:151 test path }).setProtectedHeader({ alg: 'ES256' }).sign(keypair.privateKey);
  23. test/fapi/fapi-final.test.js:184 test path }).setProtectedHeader({ alg: 'ES256' }).sign(keypair.privateKey);
  24. test/fapi/fapi-final.test.js:218 test path }).setProtectedHeader({ alg: 'ES256' }).sign(keypair.privateKey);
  25. test/fapi/fapi-final.test.js:252 test path }).setProtectedHeader({ alg: 'ES256' }).sign(keypair.privateKey);
  26. test/fapi/fapi2.test.js:88 test path }).setProtectedHeader({ alg: 'ES256' }).sign(keypair.privateKey),
  27. test/fapi/fapi2.test.js:164 test path }).setProtectedHeader({ alg: 'ES256' }).sign(keypair.privateKey);
  28. test/fapi/fapi2.test.js:195 test path }).setProtectedHeader({ alg: 'ES256' }).sign(keypair.privateKey);
  29. test/fapi/fapi2.test.js:228 test path }).setProtectedHeader({ alg: 'ES256' }).sign(keypair.privateKey);
  30. test/fapi/fapi2.test.js:261 test path }).setProtectedHeader({ alg: 'ES256' }).sign(keypair.privateKey);
  31. test/formats/jwt.test.js:535 test path alg: 'ES512',
  32. test/jwks/jwks_uri.test.js:105 test path alg: 'ES256',
  33. test/openid4vci/openid4vci.test.js:114 test path .setProtectedHeader({ alg: 'ES256', typ: 'dpop+jwt', jwk: await exportJWK(keypair.publicKey) })
  34. test/openid4vci/openid4vci.test.js:1662 test path alg: 'ES384',
  35. test/openid4vci/openid4vci.test.js:2272 test path alg: 'ES384',
  36. test/openid4vci/pre_authorized_code.test.js:194 test path alg: 'ES256',
js.jwt.algorithm · CWE-327
Ed25519 Quantum-vulnerable 16 places See details

JWT signed with a classical algorithm

A JOSE `alg` value. RS*, PS*, ES* and EdDSA sign with a quantum-vulnerable key; HS* is an HMAC and is not affected. `alg: 'none'` is reported as a critical defect today.

A quantum computer of sufficient size breaks this completely. It has to be replaced, not tuned. Broken by Shor's algorithm on a cryptographically relevant quantum computer.

What to do. No standardised post-quantum JOSE algorithm exists yet. Keep token lifetimes short.

js.jwt.algorithm · CWE-327
Ed25519 Quantum-vulnerable 12 places See details

Classical key pair generated with Node crypto

`crypto.generateKeyPair()` or its synchronous form. The detector resolves the algorithm through a `promisify()` wrapper and through an import alias, both of which are common enough that missing them would leave real key generation unreported.

A quantum computer of sufficient size breaks this completely. It has to be replaced, not tuned. Broken by Shor's algorithm on a cryptographically relevant quantum computer.

What to do. ML-KEM-768 for encryption, ML-DSA-65 for signatures. Node exposes neither yet, so this usually means an addon or a service boundary.

  1. test/attest_bindings/attest_bindings.config.js:9 test path const attestationKeyPair = generateKeyPairSync('ed25519');
  2. test/attest_bindings/attest_bindings.test.js:62 test path const instanceKeyPair = generateKeyPairSync('ed25519');
  3. test/attest_bindings/attest_bindings.test.js:98 test path const instanceKeyPair2 = generateKeyPairSync('ed25519');
  4. test/attest_bindings/attest_bindings.test.js:172 test path const instanceKeyPair = generateKeyPairSync('ed25519');
  5. test/attest_bindings/attest_bindings.test.js:211 test path const instanceKeyPair = generateKeyPairSync('ed25519');
  6. test/attest_bindings/attest_bindings.test.js:238 test path const instanceKeyPair2 = generateKeyPairSync('ed25519');
  7. test/attest_bindings/attest_bindings.test.js:268 test path const instanceKeyPair = generateKeyPairSync('ed25519');
  8. test/attest_bindings/attest_bindings.test.js:290 test path const instanceKeyPair2 = generateKeyPairSync('ed25519');
  9. test/attest_bindings/attest_bindings.test.js:320 test path const instanceKeyPair = generateKeyPairSync('ed25519');
  10. test/attest_bindings/attest_bindings.test.js:343 test path const instanceKeyPair2 = generateKeyPairSync('ed25519');
  11. test/client_auth/client_auth.test.js:1293 test path const instanceKeyPair = generateKeyPairSync('ed25519');
  12. test/client_auth/client_auth.test.js:1452 test path const instanceKeyPair = generateKeyPairSync('ed25519');
js.generatekeypair · CWE-327
RSA-PSS Quantum-vulnerable 11 places See details

JWT signed with a classical algorithm

A JOSE `alg` value. RS*, PS*, ES* and EdDSA sign with a quantum-vulnerable key; HS* is an HMAC and is not affected. `alg: 'none'` is reported as a critical defect today.

A quantum computer of sufficient size breaks this completely. It has to be replaced, not tuned. Broken by Shor's algorithm on a cryptographically relevant quantum computer.

What to do. No standardised post-quantum JOSE algorithm exists yet. Keep token lifetimes short.

  1. certification/fapi/index.js:285 alg: 'PS256',
  2. certification/fapi/index.js:307 authorization_signed_response_alg: 'PS256',
  3. certification/fapi/index.js:308 id_token_signed_response_alg: 'PS256',
  4. certification/fapi/index.js:309 request_object_signing_alg: 'PS256',
  5. test/configuration/client_metadata.test.js:2121 test path id_token_signed_response_alg: 'PS256',
  6. test/formats/jwt.test.js:76 test path sign: { alg: 'PS256' },
  7. test/formats/jwt.test.js:373 test path alg: 'PS256',
  8. test/formats/jwt.test.js:402 test path alg: 'PS256',
  9. test/registration_policies/registration_policies.test.js:95 test path id_token_signed_response_alg: 'PS256',
  10. test/registration_policies/registration_policies.test.js:120 test path id_token_signed_response_alg: 'PS256',
  11. test/registration_policies/registration_policies.test.js:142 test path id_token_signed_response_alg: 'PS256',
js.jwt.algorithm · CWE-327
ECDH Quantum-vulnerable Recorded traffic Renamed import 9 places See details

Classical key pair generated with Node crypto

`crypto.generateKeyPair()` or its synchronous form. The detector resolves the algorithm through a `promisify()` wrapper and through an import alias, both of which are common enough that missing them would leave real key generation unreported.

A quantum computer of sufficient size breaks this completely. It has to be replaced, not tuned. Broken by Shor's algorithm on a cryptographically relevant quantum computer.

What to do. ML-KEM-768 for encryption, ML-DSA-65 for signatures. Node exposes neither yet, so this usually means an addon or a service boundary.

  1. test/external_signing/external_signing.config.js:8 test path const es256 = crypto.generateKeyPairSync('ec', { namedCurve: 'P-256' });
  2. test/external_signing/external_signing.config.js:9 test path const es384 = crypto.generateKeyPairSync('ec', { namedCurve: 'P-384' });
  3. test/formats/jwt.test.js:378 test path key: (await generateKeyPair('ec', { namedCurve: 'P-256' })).publicKey,
  4. test/formats/jwt.test.js:407 test path key: (await generateKeyPair('ec', { namedCurve: 'P-256' })).publicKey,
  5. test/formats/jwt.test.js:430 test path key: (await generateKeyPair('ec', { namedCurve: 'P-256' })).publicKey,
  6. test/formats/jwt.test.js:494 test path key: (await generateKeyPair('ec', { namedCurve: 'P-256' })).publicKey,
  7. test/formats/jwt.test.js:515 test path key: (await generateKeyPair('ec', { namedCurve: 'P-256' })).privateKey,
  8. test/formats/jwt.test.js:557 test path key: (await generateKeyPair('ec', { namedCurve: 'P-256' })).privateKey,
  9. test/formats/jwt.test.js:579 test path key: (await generateKeyPair('ec', { namedCurve: 'P-256' })).publicKey,
js.generatekeypair · CWE-327
RSA-OAEP Quantum-vulnerable Recorded traffic 9 places See details

JWT signed with a classical algorithm

A JOSE `alg` value. RS*, PS*, ES* and EdDSA sign with a quantum-vulnerable key; HS* is an HMAC and is not affected. `alg: 'none'` is reported as a critical defect today.

A quantum computer of sufficient size breaks this completely. It has to be replaced, not tuned. Broken by Shor's algorithm on a cryptographically relevant quantum computer.

What to do. No standardised post-quantum JOSE algorithm exists yet. Keep token lifetimes short.

  1. test/encryption/encryption.config.js:33 test path id_token_encrypted_response_alg: 'RSA-OAEP',
  2. test/encryption/encryption.config.js:35 test path request_object_encryption_alg: 'RSA-OAEP',
  3. test/encryption/encryption.config.js:38 test path userinfo_encrypted_response_alg: 'RSA-OAEP',
  4. test/encryption/encryption.test.js:244 test path let [key] = i(this.provider).keystore.selectForEncrypt({ kty: 'RSA', alg: 'RSA-OAEP' });
  5. test/encryption/encryption.test.js:248 test path .setProtectedHeader({ enc: 'A128CBC-HS256', alg: 'RSA-OAEP' })
  6. test/encryption/encryption.test.js:285 test path let [key] = i(this.provider).keystore.selectForEncrypt({ kty: 'RSA', alg: 'RSA-OAEP' });
  7. test/encryption/encryption.test.js:289 test path .setProtectedHeader({ enc: 'A128CBC-HS256', alg: 'RSA-OAEP' })
  8. test/jwks/jwks-enc.config.js:42 test path alg: 'RSA-OAEP',
  9. test/jwks/jwks_uri.test.js:38 test path alg: 'RSA-OAEP',
js.jwt.algorithm · CWE-327
ECDH Quantum-vulnerable Recorded traffic 7 places See details

JWT signed with a classical algorithm

A JOSE `alg` value. RS*, PS*, ES* and EdDSA sign with a quantum-vulnerable key; HS* is an HMAC and is not affected. `alg: 'none'` is reported as a critical defect today.

A quantum computer of sufficient size breaks this completely. It has to be replaced, not tuned. Broken by Shor's algorithm on a cryptographically relevant quantum computer.

What to do. No standardised post-quantum JOSE algorithm exists yet. Keep token lifetimes short.

  1. test/configuration/client_keystore.test.js:44 test path id_token_encrypted_response_alg: 'ECDH-ES+A128KW',
  2. test/formats/jwt.test.js:376 test path alg: 'ECDH-ES',
  3. test/formats/jwt.test.js:405 test path alg: 'ECDH-ES',
  4. test/formats/jwt.test.js:428 test path alg: 'ECDH-ES',
  5. test/formats/jwt.test.js:577 test path alg: 'ECDH-ES',
  6. test/jwks/jwks-enc.config.js:57 test path alg: 'ECDH-ES',
  7. test/jwks/jwks_uri.test.js:54 test path alg: 'ECDH-ES',
js.jwt.algorithm · CWE-327
ECDSAsecg/secp256r1 Quantum-vulnerable 2 places See details

X.509 certificate

A PEM certificate. The subject public-key algorithm and key size are read from the SubjectPublicKeyInfo structure, and the not-after date is reported so certificates that outlive the migration window are visible.

This is a digital identity document. Its expiry date matters: one valid for many years locks in today's algorithms for that long.

What to do. Shorten certificate lifetimes so re-issuing with a post-quantum key is routine.

  1. test/jwks/client.crt:1 test path -----BEGIN CERTIFICATE-----
  2. test/jwks/ec.crt:1 test path -----BEGIN CERTIFICATE-----
pem.certificate
RSA Quantum-vulnerable Recorded traffic Renamed import 2 places See details

One-shot signing or public-key encryption

`crypto.sign()`, `crypto.verify()`, `privateEncrypt()`, `publicDecrypt()`, `privateDecrypt()` or `publicEncrypt()`. These take the key at runtime, so the algorithm follows the key; every key type Node accepts here is classical.

A quantum computer of sufficient size breaks this completely. It has to be replaced, not tuned. Broken by Shor's algorithm on a cryptographically relevant quantum computer.

What to do. ML-KEM-768 for encryption, ML-DSA-65 for signatures.

  1. test/external_signing/external_signing.config.js:25 test path return crypto.sign('sha256', data, {
  2. test/external_signing/external_signing.config.js:74 test path return crypto.sign('sha384', data, {
js.node.oneshot · CWE-327
RSA-PSS Quantum-vulnerable 2 places See details

JOSE algorithm declared in configuration

An `alg` value in JSON or YAML. `none` is reported as a critical defect; HS* is an HMAC and is not quantum-vulnerable; RS*, PS*, ES* and EdDSA are.

A quantum computer of sufficient size breaks this completely. It has to be replaced, not tuned. Broken by Shor's algorithm on a cryptographically relevant quantum computer.

What to do. No standardised post-quantum JOSE algorithm exists yet. Keep token lifetimes short.

jose.algorithm · CWE-327
ECDSA Quantum-vulnerable 1 place See details

Private key committed to the repository

A PEM private-key block. The header names the algorithm where the format is the legacy one; for PKCS#8 the algorithm OID is read out of the DER. A private key in version control is a present-day incident before it is a quantum question.

A secret key is stored in this repository's files. Anyone who can read the repository can use it. This needs attention today, regardless of quantum computers.

What to do. Revoke and rotate the key, then keep key material out of the repository. Record the algorithm in the inventory.

  1. test/jwks/ec.key:1 test path -----BEGIN EC PRIVATE KEY-----
pem.private-key · CWE-321, CWE-327
RSA Quantum-vulnerable Recorded traffic Renamed import 1 place See details

Classical key pair generated with Node crypto

`crypto.generateKeyPair()` or its synchronous form. The detector resolves the algorithm through a `promisify()` wrapper and through an import alias, both of which are common enough that missing them would leave real key generation unreported.

A quantum computer of sufficient size breaks this completely. It has to be replaced, not tuned. Broken by Shor's algorithm on a cryptographically relevant quantum computer.

What to do. ML-KEM-768 for encryption, ML-DSA-65 for signatures. Node exposes neither yet, so this usually means an addon or a service boundary.

  1. test/external_signing/external_signing.config.js:10 test path const rs256 = crypto.generateKeyPairSync('rsa', { modulusLength: 2048 });
js.generatekeypair · CWE-327
RSA2048-bit Quantum-vulnerable Recorded traffic 1 place See details

X.509 certificate

A PEM certificate. The subject public-key algorithm and key size are read from the SubjectPublicKeyInfo structure, and the not-after date is reported so certificates that outlive the migration window are visible.

This is a digital identity document. Its expiry date matters: one valid for many years locks in today's algorithms for that long.

What to do. Shorten certificate lifetimes so re-issuing with a post-quantum key is routine.

  1. test/jwks/rsa.crt:1 test path -----BEGIN CERTIFICATE-----
pem.certificate
RSA Quantum-vulnerable Recorded traffic 1 place See details

Private key committed to the repository

A PEM private-key block. The header names the algorithm where the format is the legacy one; for PKCS#8 the algorithm OID is read out of the DER. A private key in version control is a present-day incident before it is a quantum question.

A secret key is stored in this repository's files. Anyone who can read the repository can use it. This needs attention today, regardless of quantum computers.

What to do. Revoke and rotate the key, then keep key material out of the repository. Record the algorithm in the inventory.

  1. test/jwks/rsa.key:1 test path -----BEGIN RSA PRIVATE KEY-----
pem.private-key · CWE-321, CWE-327
AES-128 Reduced margin 8 places See details

JWT signed with a classical algorithm

A JOSE `alg` value. RS*, PS*, ES* and EdDSA sign with a quantum-vulnerable key; HS* is an HMAC and is not affected. `alg: 'none'` is reported as a critical defect today.

A quantum computer weakens this but does not break it. Increasing the key or digest size restores the margin. Grover's algorithm halves the effective strength; the parameter, not the design, is the problem.

What to do. No standardised post-quantum JOSE algorithm exists yet. Keep token lifetimes short.

  1. test/encryption/encryption.config.js:47 test path id_token_encrypted_response_alg: 'A128KW',
  2. test/encryption/encryption.config.js:56 test path id_token_encrypted_response_alg: 'A128KW',
  3. test/encryption/encryption.test.js:365 test path let [key] = client.symmetricKeyStore.selectForEncrypt({ alg: 'A128KW' });
  4. test/encryption/encryption.test.js:369 test path .setProtectedHeader({ enc: 'A128CBC-HS256', alg: 'A128KW' })
  5. test/encryption/encryption.test.js:401 test path let [key] = client.symmetricKeyStore.selectForEncrypt({ alg: 'A128KW' });
  6. test/encryption/encryption.test.js:405 test path .setProtectedHeader({ enc: 'A128CBC-HS256', alg: 'A128KW' })
  7. test/jwt_introspection/jwt_introspection.config.js:33 test path introspection_encrypted_response_alg: 'A128KW',
  8. test/jwt_response_modes/jwt_response_modes.config.js:29 test path authorization_encrypted_response_alg: 'A128KW',
js.jwt.algorithm · CWE-327
SHA-256 Reduced margin Renamed import 5 places See details

Hash function in use

`createHash()` or `subtle.digest()`. The digest is read from the argument, so one rule covers the family: MD5 and SHA-1 are reported as broken, SHA-256 as a reduced margin, SHA-384 and above as inventory.

A quantum computer weakens this but does not break it. Increasing the key or digest size restores the margin. Pre-image resistance falls to about 128 bits of quantum work. Adequate for most uses; SHA-384 restores the full margin where a signature must last decades.

What to do. SHA-256 as the floor, SHA-384 where the digest protects something long-lived.

  1. certification/oidc/configuration.js:191 return crypto.createHash('sha256')
  2. docs/type-contracts.js:579 return createHash('sha256').update(JSON.stringify(payload)).digest('hex');
  3. test/introspection/introspection.config.js:18 test path .createHash('sha256')
  4. test/pairwise/pairwise.config.js:13 test path .createHash('sha256')
  5. test/tools/type_contracts.test.js:189 test path createHash('sha256').update(JSON.stringify(payload)).digest('hex'),
js.hash · CWE-328
SHA-256 Reduced margin Renamed import 1 place See details

Keyed hash in use

`createHmac()`. HMAC is not broken by Shor. Reported so the inventory is complete, and raised only where the underlying digest is MD5 or SHA-1 - which still appears in TOTP and in older protocol implementations.

This is a fingerprint proving a message was not altered. Quantum computers do not break it.

What to do. No action, unless the digest is MD5 or SHA-1.

  1. test/request/jwt_request.test.js:761 test path const signature = crypto.createHmac('sha256', 'secret')
js.hmac
unknown Could not be determined 3 places See details

JWT signed with a classical algorithm

A JOSE `alg` value. RS*, PS*, ES* and EdDSA sign with a quantum-vulnerable key; HS* is an HMAC and is not affected. `alg: 'none'` is reported as a critical defect today.

The algorithm could not be established from the source. Usually it is selected while the program runs, but it may equally be that the call gives no clue, or that it is decided somewhere this scan does not reach. Somebody has to check.

What to do. No standardised post-quantum JOSE algorithm exists yet. Keep token lifetimes short.

  1. test/formats/jwt.test.js:453 test path alg: 'none',
  2. test/pushed_authorization_requests/pushed_authorization_requests.test.js:282 test path expect(header).to.deep.eql({ alg: 'none' });
  3. test/signatures/signatures.config.js:18 test path id_token_signed_response_alg: 'none',
js.jwt.algorithm · CWE-327
unknown Could not be determined 2 places See details

Key pair algorithm chosen at runtime

`generateKeyPair(x, …)` where the first argument is an identifier rather than a literal. Reported as unresolved rather than assumed.

This code picks its encryption method while it runs. A scan cannot tell which one it ends up using.

What to do. Trace the value to its configuration source and record the concrete algorithm by hand.

  1. test/keys.js:8 test path const result = await generateKeyPair(alg, { extractable: true });
  2. test/openid4vci/openid4vci.test.js:2423 test path const { privateKey } = await generateKeyPair(alg, { extractable: true });
js.generatekeypair.variable · CWE-327
unknown Could not be determined 1 place See details

Cryptographic library in the dependency manifest

A dependency known to implement classical asymmetric cryptography. Its presence is inventory, not a finding about this codebase: the library may never be called with a quantum-vulnerable algorithm.

The project depends on a cryptography library. Listed so the inventory is complete; it is not by itself a problem.

What to do. Check the version. Several of these libraries have shipped ML-KEM and ML-DSA support since 2024, so the migration may need an upgrade rather than a replacement.

  1. package.json:62 "jose": "^6.2.10",
dep.crypto-library
HMAC Quantum-safe Renamed import 34 places See details

JWT signed with a classical algorithm

A JOSE `alg` value. RS*, PS*, ES* and EdDSA sign with a quantum-vulnerable key; HS* is an HMAC and is not affected. `alg: 'none'` is reported as a critical defect today.

No known quantum attack changes how strong this is. A keyed MAC is not affected by Shor and only marginally by Grover.

What to do. No standardised post-quantum JOSE algorithm exists yet. Keep token lifetimes short.

  1. test/client_auth/client_auth.test.js:666 test path this.key = await importJWK((await this.provider.Client.find('client-jwt-secret')).symmetricKeyStore.selectForSign({ alg: 'HS256' })[0]);
  2. test/client_auth/client_auth.test.js:1147 test path const key = await importJWK((await this.provider.Client.find('secret-expired-jwt')).symmetricKeyStore.selectForSign({ alg: 'HS256' })[0]);
  3. test/configuration/client_keystore.test.js:43 test path id_token_signed_response_alg: 'HS256',
  4. test/core/implicit/implicit.config.js:16 test path id_token_signed_response_alg: 'HS256',
  5. test/dpop/dpop.test.js:666 test path .setProtectedHeader({ alg: 'HS256' })
  6. test/dynamic_registration/dynamic_registration.test.js:276 test path id_token_signed_response_alg: 'HS256',
  7. test/encryption/encryption.config.js:72 test path request_object_signing_alg: 'HS256',
  8. test/encryption/encryption.test.js:236 test path const [hsSecret] = client.symmetricKeyStore.selectForSign({ alg: 'HS256' });
  9. test/encryption/encryption.test.js:277 test path const [hsSecret] = client.symmetricKeyStore.selectForSign({ alg: 'HS256' });
  10. test/end_session/end_session.config.js:22 test path id_token_signed_response_alg: 'HS256',
  11. test/end_session/end_session.test.js:362 test path Buffer.from(JSON.stringify({ alg: 'HS256' })).toString('base64url'),
  12. test/formats/jwt.test.js:156 test path sign: { alg: 'HS256', key: crypto.randomBytes(32) },
  13. test/formats/jwt.test.js:174 test path sign: { alg: 'HS256', key: await crypto.subtle.generateKey({ name: 'HMAC', hash: 'SHA-256' }, false, ['sign']) },
  14. test/formats/jwt.test.js:192 test path sign: { alg: 'HS256', key: crypto.randomBytes(32), kid: 200 },
  15. test/formats/jwt.test.js:233 test path sign: { alg: 'HS256', key: crypto.randomBytes(32), kid: 'feb-2020' },
  16. test/formats/jwt.test.js:250 test path sign: { alg: 'HS256', key: crypto.createSecretKey(crypto.randomBytes(32)) },
  17. test/formats/jwt.test.js:473 test path alg: 'HS256',
  18. test/formats/jwt.test.js:493 test path alg: 'HS256',
  19. test/formats/jwt.test.js:514 test path alg: 'HS256',
  20. test/id_token_claims/conform.config.js:23 test path userinfo_signed_response_alg: 'HS256',
  21. test/jwt_introspection/jwt_introspection.config.js:26 test path introspection_signed_response_alg: 'HS256',
  22. test/jwt_response_modes/jwt_response_modes.config.js:38 test path authorization_signed_response_alg: 'HS256',
  23. test/pushed_authorization_requests/pushed_authorization_requests.config.js:51 test path request_object_signing_alg: 'HS256',
  24. test/pushed_authorization_requests/pushed_authorization_requests.test.js:433 test path this.key = await importJWK(client.symmetricKeyStore.selectForSign({ alg: 'HS256' })[0]);
  25. test/request/jwt_request.test.js:377 test path let [key] = client.symmetricKeyStore.selectForSign({ alg: 'HS256' });
  26. test/request/jwt_request.test.js:406 test path let [key] = client.symmetricKeyStore.selectForSign({ alg: 'HS256' });
  27. test/request/jwt_request.test.js:433 test path let [key] = client.symmetricKeyStore.selectForSign({ alg: 'HS256' });
  28. test/request/jwt_request.test.js:727 test path Buffer.from(JSON.stringify({ alg: 'HS256' })).toString('base64url'),
  29. test/request/jwt_request.test.js:913 test path let [key] = client.symmetricKeyStore.selectForSign({ alg: 'HS256' });
  30. test/request/request.config.js:38 test path request_object_signing_alg: 'HS256',
  31. test/request/request.config.js:46 test path request_object_signing_alg: 'HS256',
  32. test/rich_authorization_requests/rich_authorization_requests.config.js:188 test path request_object_signing_alg: 'HS256',
  33. test/rich_authorization_requests/rich_authorization_requests.test.js:327 test path client.symmetricKeyStore.selectForSign({ alg: 'HS256' })[0],
  34. test/signatures/signatures.config.js:25 test path id_token_signed_response_alg: 'HS256',
js.jwt.algorithm · CWE-327
AES-256 Quantum-safe 15 places See details

JWT signed with a classical algorithm

A JOSE `alg` value. RS*, PS*, ES* and EdDSA sign with a quantum-vulnerable key; HS* is an HMAC and is not affected. `alg: 'none'` is reported as a critical defect today.

No known quantum attack changes how strong this is. No known quantum algorithm changes the security margin.

What to do. No standardised post-quantum JOSE algorithm exists yet. Keep token lifetimes short.

  1. certification/fapi/index.js:332 alg: 'dir',
  2. test/configuration/client_metadata.test.js:997 test path { userinfo_encrypted_response_alg: 'dir' },
  3. test/core/implicit/implicit.config.js:25 test path id_token_encrypted_response_alg: 'dir',
  4. test/encryption/encryption.config.js:64 test path id_token_encrypted_response_alg: 'dir',
  5. test/encryption/encryption.test.js:467 test path .setProtectedHeader({ enc: 'A128CBC-HS256', alg: 'dir' })
  6. test/encryption/encryption.test.js:503 test path .setProtectedHeader({ enc: 'A128CBC-HS256', alg: 'dir' })
  7. test/formats/jwt.test.js:211 test path alg: 'dir',
  8. test/formats/jwt.test.js:270 test path alg: 'dir',
  9. test/formats/jwt.test.js:297 test path alg: 'dir',
  10. test/formats/jwt.test.js:324 test path alg: 'dir',
  11. test/formats/jwt.test.js:351 test path alg: 'dir',
  12. test/formats/jwt.test.js:555 test path alg: 'dir',
  13. test/formats/jwt.test.js:600 test path alg: 'dir',
  14. test/jwt/jsonwebtoken.test.js:166 test path alg: 'dir', enc: 'A128GCM',
  15. test/jwt/jsonwebtoken.test.js:187 test path alg: 'dir', enc: 'A128GCM',
js.jwt.algorithm · CWE-327
CSPRNG Quantum-safe Renamed import 10 places See details

Random number generation

`crypto.randomBytes()`, `randomUUID()` or `getRandomValues()`. A platform CSPRNG is not a quantum exposure; it is recorded because an inventory that omits the randomness source is incomplete. `Math.random()` is a separate, present-day defect.

This is where the software gets its random numbers. Quantum computers do not weaken it.

What to do. No action.

  1. certification/fapi/index.js:105 const eKey = crypto.randomBytes(32);
  2. certification/oidc/configuration.js:173 nonceSecret: crypto.randomBytes(32),
  3. certification/oidc/index.js:53 ctx.res.locals.cspNonce = crypto.randomBytes(16).toString('base64');
  4. lib/helpers/defaults.js:277 return crypto.randomBytes(64).toString('base64url');
  5. lib/shared/xsrf.js:7 const secret = crypto.randomBytes(24).toString('hex');
  6. test/attest_bindings/attest_bindings.test.js:39 test path .setJti(crypto.randomUUID())
  7. test/fapi/fapi2.test.js:82 test path jti: crypto.randomUUID(),
  8. test/formats/jwt.test.js:156 test path sign: { alg: 'HS256', key: crypto.randomBytes(32) },
  9. test/request/jwt_request.test.js:70 test path this.code_verifier = crypto.randomBytes(32).toString('base64url');
  10. test/test_helper.js:264 test path this.state = 'state' in parameters ? parameters.state : crypto.randomBytes(16).toString('base64url');
js.rng

Cryptographic assets

Algorithm Assessment What it means Occurrences
unknown Could not be determined The algorithm could not be established from the source - chosen at runtime, or decided somewhere this scan does not reach. 86
ECDSA Quantum-vulnerable Broken by Shor's algorithm on a cryptographically relevant quantum computer. 39
HMAC Quantum-safe A keyed MAC is not affected by Shor and only marginally by Grover. 34
RSA-PKCS1v15 Already broken PKCS#1 v1.5 encryption padding is vulnerable to Bleichenbacher oracles today, and the underlying RSA is broken by Shor. 34
Ed25519 Quantum-vulnerable Broken by Shor's algorithm on a cryptographically relevant quantum computer. 28
ECDH Quantum-vulnerable Broken by Shor's algorithm on a cryptographically relevant quantum computer. 16
AES-256 Quantum-safe No known quantum algorithm changes the security margin. 15
RSA-PSS Quantum-vulnerable Broken by Shor's algorithm on a cryptographically relevant quantum computer. 13
CSPRNG Quantum-safe A cryptographically secure random number generator provided by the platform. Not weakened by a quantum computer. 10
RSA-OAEP Quantum-vulnerable Broken by Shor's algorithm on a cryptographically relevant quantum computer. 9
AES-128 Reduced margin Grover's algorithm halves the effective strength; the parameter, not the design, is the problem. 8
SHA-256 Reduced margin Pre-image resistance falls to about 128 bits of quantum work. Adequate for most uses; SHA-384 restores the full margin where a signature must last decades. 6
RSA Quantum-vulnerable Broken by Shor's algorithm on a cryptographically relevant quantum computer. 5

Imported cryptographic libraries

Library Files
node:crypto — the Node crypto module 67