worldfnd / worldfnd/provekit

noir_pasport: pubkey offset not bounds-checked against tbs_certificate_len; key can be extracted from the unsigned tail

Open Beginner friendly
#381 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Noir
Stars
138
Forks
47
Avg merge
1d 34m
Merged PRs (30d)
6

Description

Description

verify_rsa_pubkey_in_tbs accepts an arbitrary prover-supplied pubkey_offset and verifies that the DSC modulus bytes appear at that offset. It does not assert:

pubkey_offset + DSC_KEY_SIZE <= tbs_certificate_len

A prover can point the offset into the unsigned (zero-padded) tail of the 1300-byte buffer, extract attacker-controlled bytes, and have them "verified" against the CSCA signature — even though those bytes were never signed by the CSCA.

Root Cause

verify_rsa_pubkey_in_tbs takes tbs: [u8; N] and pubkey_offset: u32 but has no access to the signed length. The function only checks that modulus bytes match at the offset, with no upper-bound constraint on the offset relative to the authenticated region.

Affected file(s):

File Notes
noir-examples/noir-passport-monolithic/utils/data-check/tbs-pubkey/src/lib.nr verify_rsa_pubkey_in_tbs — missing bound check
noir-examples/noir-passport-monolithic/utils/passport_validity_check/src/lib.nr call site — must thread tbs_certificate_len through
Fix

Add a tbs_certificate_len: u32 parameter to verify_rsa_pubkey_in_tbs and assert the bound before the byte comparison loop:

assert(pubkey_offset + DSC_KEY_SIZE <= tbs_certificate_len);

The call site in passport_validity_check/src/lib.nr must be updated to thread tbs_certificate_len through accordingly.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in noir-examples/noir-passport-monolithic/utils/data-check/tbs-pubkey/src/lib.nr at verify_rsa_pubkey_in_tbs, then inspect its call site in noir-examples/noir-passport-monolithic/utils/passport_validity_check/src/lib.nr. Thread tbs_certificate_len through the call and enforce that the public-key range stays within it before the byte comparison. Done means offsets into the unsigned tail are rejected.

Written by the indexing model from the issue text.

Assessment

Domain
cryptography, security
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.