Skip to content

Validate release-feed version and verify download checksums (HackerOne #3764025) - #45

Merged
jsokol merged 1 commit into
mainfrom
fix/version-feed-command-injection
Sep 20, 2026
Merged

jsokol merged 1 commit into
mainfrom
fix/version-feed-command-injection

Conversation

@jsokol

@jsokol jsokol commented Sep 20, 2026

Copy link
Copy Markdown
Member

Summary

  • get_current_simplerisk_version() fetched the version string from releases.xml with no validation, and set_up_simplerisk() interpolated it unescaped into wget/tar commands run through exec_cmdbash -c. A compromised feed (or its GitHub fallback, or a trusted-CA MITM) could embed shell metacharacters in the version attribute and get root code execution on every install/upgrade, since the script enforces EUID==0.
  • Fixed with two independent layers, since either alone would leave a gap:
    • get_current_simplerisk_version() now rejects anything that doesn't match releases.xml's real version format (YYYYMMDD-NNN) before the value is used anywhere.
    • set_up_simplerisk()'s wget/tar calls are converted from exec_cmd (bash -c string interpolation) to run_cmd (array-safe, argv passed directly), so the version string is never re-evaluated by a shell at all, regardless of the regex above.
  • Also verifies the downloaded bundle and database.sql against the bundle_sha256/database_schema sha256 that releases.xml already publishes per release (new verify_sha256()), aborting on mismatch. This closes a second gap the two changes above don't: an artifact host (S3, GitHub raw) or the download itself being tampered with independently of releases.xml.

Reported via HackerOne #3764025.

Test plan

  • Reproduced the exact malicious version string from the report against the patched code — confirmed rejection before it reaches any shell context.
  • Fetched the real releases.xml and confirmed version + both checksums parse correctly.
  • Downloaded the real bundle and confirmed checksum verification passes.
  • Tampered with a downloaded file and confirmed verify_sha256 catches it and aborts.
  • Full install → verify-install (43/43) → uninstall → verify-uninstall (13/13) on a fresh Ubuntu 22.04 container — no regression. The fixed code path is OS-agnostic (shared identically by every supported OS family's setup function), so this covers Debian/CentOS/RHEL/openSUSE/SLES as well.
  • CI run on this PR.

…a root command-injection path

get_current_simplerisk_version() fetched the version string from
releases.xml with no validation, and set_up_simplerisk() interpolated
it unescaped into wget/tar commands run through exec_cmd -> bash -c.
A compromised feed (or its GitHub fallback, or a trusted-CA MITM)
could embed shell metacharacters in the version attribute and get
root code execution on every install/upgrade, since the script
enforces EUID==0.

Two independent layers of defense, since either alone would leave a
gap:

- get_current_simplerisk_version() now rejects anything that doesn't
  match releases.xml's actual version format (YYYYMMDD-NNN) before
  the value is used anywhere.
- set_up_simplerisk()'s wget/tar calls are converted from exec_cmd
  (bash -c string interpolation) to run_cmd (array-safe, argv passed
  directly), so the version string is never re-evaluated by a shell
  at all, regardless of the regex above.

Also verifies the downloaded bundle and database.sql against the
bundle_sha256/database_schema sha256 releases.xml already publishes
for each release (verify_sha256()), aborting on any mismatch. This
closes a second gap the regex/run_cmd changes don't: an artifact host
(S3, GitHub raw) or the download itself being tampered with
independently of releases.xml.

Verified: the exact malicious version string from the report is now
rejected before reaching any shell context; the real releases.xml's
version and both checksums parse and verify correctly against a real
download; a tampered downloaded file is correctly caught and rejected;
and a full install -> verify -> uninstall -> verify cycle against a
fresh Ubuntu 22.04 container shows no regression (the fixed code path
is OS-agnostic, shared identically by every supported OS family).

Reported via HackerOne #3764025.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jsokol
jsokol merged commit 34c5419 into main Sep 20, 2026
8 checks passed
@jsokol
jsokol deleted the fix/version-feed-command-injection branch September 20, 2026 18:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant