Skip to content
This repository was archived by the owner on Mar 15, 2026. It is now read-only.

Commit 2d67997

Browse files
authored
clarify downgrade-attack mitigation for community mirrors (#581)
1 parent 648a809 commit 2d67997

1 file changed

Lines changed: 23 additions & 7 deletions

File tree

content/en-US/download/community-mirrors.smd

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,26 @@ mirrors = http_get("https://ziglang.org/download/community-mirrors.txt")
5252
shuffled = shuffle_lines(mirrors)
5353
for mirror_url in shuffled:
5454
tarball = http_get(f"{mirror_url}/{tarball_name}?source=my_automation_name")
55-
if success:
56-
# NEVER SKIP THIS STEP. The signature must be verified before the tarball is deemed safe.
57-
signature = http_get(f"{mirror_url}/{tarball_name}.minisig?source=my_automation_name")
58-
if success and minisign_verify(tarball, signature, pubkey):
59-
print("Successfully fetched Zig 0.14.1!")
55+
if not success:
56+
continue # failed to download tarball
57+
58+
# NEVER SKIP THESE STEPS. The signature must be verified before the tarball is deemed safe.
59+
signature = http_get(f"{mirror_url}/{tarball_name}.minisig?source=my_automation_name")
60+
if not success:
61+
continue # failed to download signature file
62+
63+
if not minisign_verify(tarball, signature, pubkey):
64+
continue # failed to verify signature file
65+
66+
# The signature files provided by the ZSF include a "file" field in the trusted
67+
# comment that indicates the tarball the signature applies to.
68+
# This must be verified against the requested tarball name to prevent downgrade attacks.
69+
actual_tarball_name = minisign_signature_parse_filename(signature)
70+
if actual_tarball_name != tarball_name:
71+
continue # wrong tarball provided
72+
73+
print("Successfully fetched Zig 0.14.1!")
74+
break
6075
```
6176

6277
Because ziglang.org does not have guaranteed uptime, the `community-mirrors.txt` file may at times become inaccessible. For this reason, you may wish to
@@ -81,9 +96,10 @@ Written more precisely, here is the key information and recommend workflow for d
8196
* `404 Not Found` is a permitted response when requesting Zig releases 0.5.0 or earlier, or Zig development builds earlier than the current latest release.
8297
* `504 Gateway Timeout` indicates that the tarball is unavailable because `https://ziglang.org/` is currently inaccessible (and the tarball is not in the mirror's cache).
8398
* Otherwise, feel free to [open an issue](https://github.com/ziglang/www.ziglang.org/issues/new) to inform us of the problem.
84-
* The Zig Software Foundation can never guarantee the security of any mirror, so every time a tarball is downloaded, it is **essential** to also download the minisign signature (suffix the filename with ".minisig") and verify it against the ZSF's public key (which you should copy from the ziglang.org/download page). **Never skip this step.**
99+
* After downloading a tarball, the following verification steps are required: **(never skip these steps)**
100+
* Every time a tarball is downloaded, it is **essential** to also download the minisign signature (suffix the filename with ".minisig") and verify it against the ZSF's public key (which you should copy from the ziglang.org/download page).
101+
* To prevent downgrade attacks, a "file" field in the [trusted comment](https://jedisct1.github.io/minisign/#:~:text=Trusted%20comments) is provided that must be verified to match the name of the requested tarball. The reference implementation, `minisign`, will verify the trusted comment but does **not** look for a "file" field, so this verification step must be implemented manually.
85102
* If a mirror responds with `200 OK` but signature validation fails on the returned tarball, feel free to [open an issue](https://github.com/ziglang/www.ziglang.org/issues/new) to inform us of the problem.
86-
* When the minisig signature is verified, it is also necessary to validate its **trusted comment** (which the reference implementation `minisign` always does), and ensure that its "file" field matches the name of the requested tarball, to prevent downgrade attacks.
87103

88104
## Hosting a Mirror
89105

0 commit comments

Comments
 (0)