You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(security): fail closed when the snapshot checksum is unavailable
Whether a snapshot was verified at all was decided by pre.HasMD5Sidecar,
a flag set from a plaintext HEAD of the .md5sum URL. Anyone on the path
could answer that HEAD with a 404 and the tarball was then extracted with
expectedMD5 empty, no error, exit 0 - the attacker-controlled response was
effectively a 'skip integrity checking' switch, and the CLI reported
'(md5 sidecar absent - not verified)' as a success.
The sidecar is now fetched unconditionally whenever the operator has not
opted out, and a 404, non-200 or transport failure returns a typed
VerificationUnavailableError before any tarball byte is requested, so
nothing is written. Driven A/B against a binary built from develop: base
extracts attacker state with exit 0 on a 404, a 500 and a transport reset;
this refuses all three with an empty destination.
The MCP snapshot_download tool had no opt-out at all, so it always
extracted unverified on a 404; it gains a no_verify arg alongside the
CLI's existing --no-verify, which survives the --detach re-exec.
All eight mirrors were re-probed and every one returns 200 with a
coreutils-format body, so no in-repo caller needs the opt-out. The docs
still say sidecars can be absent - corrected to say the download now
refuses rather than extracting.
Adds one additive optional field to snapshot-download.schema.json, so
SchemaVersion goes 1.12.2 -> 1.12.3 with a regenerated baseline.
downloadCmd.Flags().BoolVar(&dlNoVerify, "no-verify", false, "Extract without checking the MD5 sidecar (UNSAFE; otherwise a missing sidecar aborts the download)")
Copy file name to clipboardExpand all lines: internal/mcp/tools_snapshot.go
+16-6Lines changed: 16 additions & 6 deletions
Original file line number
Diff line number
Diff line change
@@ -32,6 +32,12 @@ type snapshotDownloadArgs struct {
32
32
Forcebool`json:"force,omitempty" jsonschema:"overwrite an existing chain DB (DESTRUCTIVE)"`
33
33
DryRunbool`json:"dry_run,omitempty" jsonschema:"print the plan and exit without downloading"`
34
34
SHA256string`json:"sha256,omitempty" jsonschema:"expected SHA-256 of the tarball (64 hex chars) obtained out of band; a mismatch fails the download. The mainnet mirrors are cleartext HTTP and their .md5sum sidecar rides the same channel, so this pin is the only check that can detect a substituted archive"`
35
+
// NoVerify is the deliberate opt-out from integrity checking. Without
36
+
// it, a sidecar that cannot be fetched aborts the download instead of
37
+
// silently extracting unverified chain data — mirroring `--no-verify`
38
+
// on the CLI so an agent isn't stuck when a mirror genuinely stops
39
+
// publishing sidecars.
40
+
NoVerifybool`json:"no_verify,omitempty" jsonschema:"UNSAFE: extract without checking the MD5 sidecar; otherwise a missing/unfetchable sidecar aborts the download"`
Description: `Stream a snapshot tarball into a destination directory, gunzip + tar in one pipeline (no .tgz on disk). Pre-checks free disk space (HEAD probe + Statfs, requires 2× headroom). Refuses overwrite of an existing chain DB unless force=true. Preserves any pre-existing userdata/. MD5-verifies inline against the published sidecar when present.
68
+
Description: `Stream a snapshot tarball into a destination directory, gunzip + tar in one pipeline (no .tgz on disk). Pre-checks free disk space (HEAD probe + Statfs, requires 2× headroom). Refuses overwrite of an existing chain DB unless force=true. Preserves any pre-existing userdata/. MD5-verifies inline against the published sidecar; if the sidecar cannot be fetched the download fails instead of extracting unverified chain data — pass no_verify=true only to accept that risk deliberately.
63
69
64
70
Use dry_run=true to inspect the plan first. The tool emits MCP progress notifications during the actual download so the client can render a live progress bar. NOTE: this MCP tool runs the download in-process and blocks until completion or context cancellation; for fire-and-forget mainnet-full sized downloads (multi-hour) prefer the CLI with --detach.
"md5_verified": { "type": "boolean", "description": "The upstream .md5sum sidecar matched. On a plaintext_transport mirror the sidecar arrives over the same unauthenticated channel as the tarball, so this attests transfer integrity only — not provenance." },
27
+
"verification_skipped": {
28
+
"type": "boolean",
29
+
"description": "true only when --no-verify / no_verify was passed. A missing or unfetchable .md5sum sidecar is an error (VERIFICATION_UNAVAILABLE), never a silent skip, so md5_verified=false always means the operator opted out."
0 commit comments