Zion Boggan

In-depth vulnerability research, detection engineering & applied cryptography.

● Open to security-research & detection roles
GitHub · LinkedIn · Email
← Research notebook
Methodology

sequoia-pgp hunt, iteration 1 (recon)

Time: 2026-04-17 ~08:18 UTC Target: sequoia-pgp (assumed YWH STF, confirm against intel file when desktop scrape lands) Source: gitlab.com/sequoia-pgp/sequoia, shallow clone at source/sequoia/ Latest commit: c67789b (today, 2026-04-17 09:45 +0200) Latest openpgp tag: openpgp/v2.2.0

Why this target

  • Active project, fresh upstream activity today.
  • Multiple historical RUSTSEC advisories on sequoia-openpgp (DoS class).
  • Parser-heavy crate (openpgp/src/parse/, ~7400 LoC of parsers).
  • Adjacent to openpgpjs hunt, variant cross-pollination opportunity.

Historical RUSTSEC anchors (variant seeds)

RUSTSEC-2024-0345 (CVE-2024-58261)

  • cert::raw::RawCertParser infinite loop on unsupported cert version.
  • Root cause class: parser does not advance input stream when encountering an unhandled tag/version, so the next iteration sees the same bytes.
  • Variant probe: enumerate all parser dispatch tables (packet body, subpacket, signature subtype, key type) and check each fall-through arm advances cursor.

RUSTSEC-2023-0038 (CVE-2023-53160)

  • “Several bugs” of attacker-controlled OOB array index → panic (DoS).
  • Root cause class: unchecked slice[idx] after parsing a length field.
  • Variant probe: grep for \[\w+ as usize\] and indexed access patterns in mpis.rs, packet/, parse/, verify each is preceded by a bounds check derived from the same input.

Parser surface map (openpgp/src/parse/)

File LoC Role Priority
stream.rs 4321 verification / decryption / streaming primitives P1
mpis.rs 666 RSA/DSA/ECDSA/EdDSA MPI parsing P2
hashed_reader.rs 644 sig hash input wrapper P2
packet_pile_parser.rs 551 packet collection P2
packet_parser_builder.rs 525 parser config / dispatch P3
partial_body.rs 426 partial body length encoding P1 (CVE-history)
map.rs 280 metadata P3

Cross-project variant, CVE-2025-47934 analog

openpgpjs message.verify() mutated the packet list while computing signatures against the pre-mutation window, so result.data could come from a different window than the verified signature. Same class to look for in sequoia/openpgp/src/parse/stream.rs Verifier / DecryptorBuilder paths: does the verified-data window equal the data delivered to the caller?

Next iteration plan

  1. Read parse/stream.rs Verifier::verify and DecryptorWithMDC paths.
  2. Map data-flow: input bytes → hash context → signature check → data delivered.
  3. Compare with the openpgpjs anti-pattern.
  4. If clean, pivot to RawCertParser dispatch tables for variant of -0345.

Source · github.com/zionsworking/security-research-notebook · methodology/sequoia-pgp-variant-hunting-1.md