Commit b468e95
sec(crypto-gate): the discovery gate could not read half its corpus (BACKLOG #1172) (#790)
The ASVS 11.1.3 crypto-inventory gate is `import ast` over `*.py`, so a weak-PRNG
draw in the TypeScript extension was invisible to it by construction. It did not
merely omit `ide/` from WALK_ROOTS; adding the directory there would have been a
no-op that looked like a fix, because the Python AST scanner finds zero `.py`
files under it and reports clean.
Add a second arm to the same required context. `check_non_python_randomness`
walks `ide/` for `.ts`/`.js` randomness sources and diffs them against
`NON_PYTHON_INVENTORY` the same bidirectional way, so a weak draw in the shipped
extension now blocks a merge. The extension's own negative test could not do that
from a leg `ci-gate` does not require.
Three properties, each pinned by a test and each proven by a mutation control run
against the shipped code rather than asserted:
* it FINDS a planted `Math.random()` in a `.ts` file. Deleting the pattern reds
6 tests.
* it does NOT flag the legitimate `randomBytes` draw in `ide/src/cspNonce.ts`,
which is the hard case: that file names `Math.random` twice in prose to explain
why it is unusable. Disabling the comment skip reds the false-positive guard.
* it REFUSES an empty walk. A scan reaching no files, and an inventory anchor
that has gone missing, both red. Disabling the empty-walk refusal reds 1 test.
A weak source has no inventory row available to it by construction. Registering
one is the move #1172 names as a disqualified pass for ASVS 11.5.1, so the weak
check runs before the inventory diff and no row can silence it.
The randomness half is the whole claim the arm supports. The extension's TLS
floor is still outside both arms, and PowerShell under `scripts/` is still
outside the Python one; that gap stays filed under #1164.
Also on #1172, which stays OPEN because its closing act is a vaulted scorecard
re-score that no engine checkout may perform:
* correct the dead clause at the top of the row. It asserted that the extension
mints its CSP nonces from `Math.random()`, which was true when filed and was
superseded by PR #422 on 2026-08-17. Struck rather than deleted, because the
evidence that the row was once wrong is what stops the next reader trusting the
rest of it unchecked.
* record the five zero-margin values the item's caveat said its census flags. An
AST census over the five walk roots finds 21 CSPRNG call sites outside tests
and resolves exactly five distinct values to 128 bits: four in the engine
(sandbox request id, upload file id, STOW-RS boundary, WS-Security nonce) and
one in the console (CSP nonce). AST rather than grep, which returns 36 lines
because a docstring naming a draw matches as readily as a draw.
* write the handoff for the two acts that remain: the ASVS 11.5.1 scorecard
re-score and the scope-completeness adversarial pass that was never run,
naming the engine-side evidence and where it lives without reproducing any
vaulted content.
Co-authored-by: wshallwshall <mefordev@messagefoundry.org>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>1 parent 20ee0fd commit b468e95
3 files changed
Lines changed: 480 additions & 15 deletions
File tree
- docs
- scripts/security
- tests
0 commit comments