Skip to content

libsodium source is downloaded without integrity verification or retry #1071

Description

@boorad

Found while triaging an unrelated CI failure on #1070. Two separate problems in the same code path, one reliability and one security.

What happened

The iOS e2e job failed at pod install:

[QuickCrypto] ⬇️  Downloading libsodium source...
curl: (6) Could not resolve host: download.libsodium.org
[!] Invalid `QuickCrypto.podspec` file: Failed to download libsodium.

A single DNS blip on a GitHub runner red-lights the whole build. The host was fine again minutes later, so it was transient — but there's no retry, so any hiccup at download.libsodium.org fails every pod install with SODIUM_ENABLED=1.

The security part

QuickCrypto.podspec:77 downloads the libsodium source tarball and compiles it, with no checksum, no signature check, and no pinned hash:

system("curl -sSfL ... -o ios/libsodium.tar.gz https://download.libsodium.org/libsodium/releases/libsodium-#{sodium_version}-stable.tar.gz") || raise(...)
system("tar -xzf ios/libsodium.tar.gz -C ios") || raise(...)

Whatever that host returns gets extracted and built into a cryptography library. TLS covers the transport, but nothing pins what we expect to receive — a compromised mirror, a hijacked domain, or a maintainer-side republish under the same URL would be compiled silently.

We already do this correctly for OpenSSL in the same file — download, verify a pinned SHA-256, fail loudly on mismatch. libsodium should meet the same bar, since it's the one we build from source rather than consume as a verified binary.

A second, weaker copy

prepare_command (line 95) downloads the same tarball again with:

curl -L -o ios/libsodium.tar.gz https://download.libsodium.org/...

Note -L without -f: on an HTTP error, curl writes the error page to libsodium.tar.gz and exits 0, so the failure surfaces later as a confusing tar error instead of a download error.

The version is also hardcoded as a literal 1.0.22 here while line 68 uses sodium_version, so the two can drift.

Suggested fix

  1. Pin a SHA-256 for the libsodium tarball and verify it, mirroring the OpenSSL block.
  2. Add --retry 3 --retry-all-errors to both fetches.
  3. Add -f to the prepare_command curl.
  4. Use a single version constant in both places.

Optionally verify libsodium's minisign signature instead of a pinned hash, though a pinned hash is simpler and stronger against republishing.

Scope

Only affects SODIUM_ENABLED=1 builds. Not a regression — this predates #1070, which doesn't touch these lines.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    buildIssue building libraryrubyPull requests that update ruby codesecuritySecurity-related issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions