Skip to content

v5.1.1

Choose a tag to compare

@github-actions github-actions released this 21 Jul 08:38
v5.1.1
e8f1f51

Send v5.1.1

One change since v5.1.0:
the origin now sends Cache-Control: no-transform, so a CDN in front of Send
cannot rewrite the responses it serves.

This is the build that powers send.anoni.net.

Nothing about how Send works has changed

The wire protocol, the URL format and the encryption are untouched. Existing
share links keep working. ffsend and other third-party clients keep working.
/__version__ still reports the API generation in version (v3.4.27) and our
release in release (now v5.1.1). This is a server-only change, so the
webpack output and its reproducibility are identical to v5.1.0.

Why this release exists

Running behind Cloudflare, we found that JavaScript Detections (part of Bot
Fight Mode) injects a third-party <script> into the HTML. It reuses the
page's own CSP nonce, so the script runs despite a nonce-based
script-src policy that is supposed to admit only our own scripts.

For a service whose security rests on the served JavaScript being the audited,
reproducible build, that injection is the whole threat: on the key-bearing
download page, code we never wrote and cannot see runs alongside the
decryption. And because the injected loader lives in dynamic HTML, it is not in
SHA256SUMS — byte verification of dist/ still passes while third-party code
runs on the page.

No Cloudflare plan, Pro included, exposes a per-hostname switch for this; the
dashboard toggle is zone-wide. The mechanism that does work per-hostname, on any
plan, is an origin response that carries Cache-Control: no-transform: the CDN
then passes the bytes through untouched and skips the injection.

What changed

  • HTML and API responses carry no-transform, so the injection is skipped
    on every page, including the download page and the error pages.
  • Static assets carry no-transform too, so Cloudflare Polish cannot
    re-compress served images. The bytes a visitor receives now match dist/, and
    the SHA256SUMS in this release, even behind a CDN.

If you run Send behind your own CDN or reverse proxy, this is the header to keep
intact. The bundled nginx-send.conf.example in the deployment repo also adds
no-transform on HTML as a second layer.

Verify this release

docker pull ghcr.io/anoni-net/send:5.1.1

cosign verify ghcr.io/anoni-net/send:5.1.1 \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --certificate-identity-regexp '^https://github.com/anoni-net/send/.github/workflows/publish.yml@.*$'

SHA256SUMS.txt below lists the sha256 of every file the server serves to a
browser, and it is signed:

cosign verify-blob SHA256SUMS.txt \
  --bundle SHA256SUMS.txt.cosign.bundle \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --certificate-identity-regexp '^https://github.com/anoni-net/send/.github/workflows/publish.yml@.*$'

VERIFYING.md walks
through checking what an instance served you, the image signature, and rebuilding
from source.

Pin by digest in production so the tag cannot move under you:
ghcr.io/anoni-net/send@sha256:c61478d7dbf37d2e7014d13040c892c81de6bae1e9079b195ac21306ef527528

Credit

Send was built by Mozilla and kept alive by
Tim Visée after Firefox Send shut down. This
release stands on both. We are not affiliated with, nor endorsed by, either.


Send v5.1.1(正體中文)

v5.1.0 起只有一個
改動:origin 回應現在帶 Cache-Control: no-transform,讓前面的 CDN 不能改寫
Send 送出的回應。

這就是 send.anoni.net 所使用的版本。

Send 的運作方式完全沒有改變

傳輸協定、URL 格式與加密都沒有動過。既有的分享連結繼續可用,ffsend 與其他
第三方客戶端也繼續可用。/__version__ 仍然分開回報 API 世代(version
v3.4.27)與我們自己的版號(release,現在是 v5.1.1)。這是純伺服器端的
改動,所以 webpack 產物與它的可重現性都與 v5.1.0 完全相同。

這個版本為什麼存在

在 Cloudflare 後面運作時,我們發現 JavaScript Detections(Bot Fight Mode
的一部分)會把一段第三方 <script> 注入 HTML。它重用頁面自己的 CSP nonce,
所以即使 script-src 是 nonce-based、理應只接受我們自己的 script,這段注入
照樣執行。

對一個安全性建立在「送出的 JavaScript 就是可稽核、可重現的那一份」的服務來說,
這段注入就是核心威脅:在帶金鑰的下載頁上,一段我們從未寫過、也看不到的程式碼
和解密一起執行。而因為注入的載入器活在動態 HTML 裡,它不在 SHA256SUMS 中,
dist/ 的逐位元驗證仍會通過,頁面上卻跑著第三方程式碼。

Cloudflare 任何方案(含 Pro)都沒有 per-hostname 的開關可以關掉它,儀表板上的
開關是 zone 層級。真正能做到 per-hostname、且在任何方案都有效的機制,是讓
origin 回應帶 Cache-Control: no-transform:CDN 就會原封不動放行,跳過注入。

改了什麼

  • HTML 與 API 回應no-transform,所以每一頁都跳過注入,包含下載頁與
    錯誤頁。
  • 靜態資源也帶 no-transform,所以 Cloudflare Polish 不能對送出的圖片
    再壓縮。訪客收到的位元組現在與 dist/、與這個版本的 SHA256SUMS 一致,即使
    在 CDN 後面也是。

如果你把 Send 放在自己的 CDN 或反向代理後面,這是要保持不被改動的標頭。部署
repo 裡的 nginx-send.conf.example 也在 HTML 上補了一層 no-transform

驗證這個版本

docker pull ghcr.io/anoni-net/send:5.1.1

cosign verify ghcr.io/anoni-net/send:5.1.1 \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --certificate-identity-regexp '^https://github.com/anoni-net/send/.github/workflows/publish.yml@.*$'

下方的 SHA256SUMS.txt 列出伺服器會送給瀏覽器的每一個檔案的 sha256,而且它有
簽章:

cosign verify-blob SHA256SUMS.txt \
  --bundle SHA256SUMS.txt.cosign.bundle \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --certificate-identity-regexp '^https://github.com/anoni-net/send/.github/workflows/publish.yml@.*$'

VERIFYING.md 說明如何
檢查某個實例送給你的東西、映像簽章,以及從原始碼重新建置。

正式環境請用 digest 固定版本,這樣 tag 就不會在你不知情的情況下被移動:
ghcr.io/anoni-net/send@sha256:c61478d7dbf37d2e7014d13040c892c81de6bae1e9079b195ac21306ef527528

致謝

Send 由 Mozilla 打造,並在 Firefox Send 關閉之後由
Tim Visée 維持存續。這個版本站在兩者之上。
我們與他們沒有從屬關係,也未獲得他們背書。