Commit 3b9bd31
committed
fix(mcp): SHA-256 the launch fingerprint — shortHash was forgeable in minutes
Review on #55, and the most serious finding of the series. It is a real break of
the launch gate, not a theoretical weakness.
launchFingerprint used shortHash — a 32-bit djb2 variant emitted as 6 base36
chars, so a ~2^31 output space. That helper exists to truncate tool names stably;
it was never meant to carry an authorization decision, and I reached for it out of
convenience.
Why it is exploitable rather than merely weak: the attacker AUTHORED the benign
command that earned trust, so they know the target value exactly, and they control
the replacement. That makes this a second preimage, not a birthday collision.
Measured on one core: 1,019,215,873 candidate hashes in 150s (~6.8M/sec) against a
2.15e9 space — so ~5 minutes of offline work to find a malicious command whose
fingerprint matches. Ship it in a later commit and the gate says "already trusted"
and spawns it silently. That is RCE with the consent prompt bypassed.
Now SHA-256 over canonical material. Two further hardenings:
* env pairs are STRUCTURAL — [[k, v]] sorted — not joined into "k=v". Joining is
ambiguous: {'a': 'b=c'} and {'a=b': 'c'} both flatten to "a=b=c", handing over a
collision for free in the one function where collisions are the threat.
* a non-array args no longer reaches .map and throws, per the same review.
No migration concern: S4b has not shipped, so no trust store exists in the wild.
Had it shipped, changing the hash would invalidate stored fingerprints and re-prompt
once — the safe direction.
A known-answer test pins the digest so a future "simplification" back to a short
hash fails loudly rather than quietly.
56 mcpConfig cases; 23 suites, 0 failures.1 parent d939ab0 commit 3b9bd31
3 files changed
Lines changed: 79 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
121 | 121 | | |
122 | 122 | | |
123 | 123 | | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
124 | 132 | | |
125 | 133 | | |
126 | 134 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
23 | | - | |
| 23 | + | |
| 24 | + | |
24 | 25 | | |
25 | 26 | | |
26 | 27 | | |
27 | 28 | | |
28 | 29 | | |
29 | 30 | | |
| 31 | + | |
30 | 32 | | |
31 | 33 | | |
32 | 34 | | |
| |||
488 | 490 | | |
489 | 491 | | |
490 | 492 | | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
491 | 501 | | |
492 | 502 | | |
493 | 503 | | |
494 | | - | |
495 | | - | |
496 | | - | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
497 | 516 | | |
498 | 517 | | |
499 | 518 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
611 | 611 | | |
612 | 612 | | |
613 | 613 | | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
614 | 662 | | |
615 | 663 | | |
616 | 664 | | |
| |||
0 commit comments