Skip to content

Harden the CLI's downloads, the installers and the workflows - #128

Merged
linroid merged 1 commit into
mainfrom
fix/review-low-cli
Oct 28, 2026
Merged

linroid merged 1 commit into
mainfrom
fix/review-low-cli

Conversation

@linroid

@linroid linroid commented Oct 28, 2026

Copy link
Copy Markdown
Owner

The low-severity CLI and tooling findings from a security review, in one change. No behaviour changes for a normal install from github.com.

  • Scratch directories (KiffVersions.install, ReleaseCommand.verify): createDirectories accepted a pre-existing directory of the same name in a shared $TMPDIR; the scratch directory is now created with mustCreate, and release --verify restores into a directory of its own rather than at a predictable file name a link could be planted at.
  • curl (Curl.fetch): --proto-redir =https when the URL is https (an http mirror, as the tests use, may still redirect freely), --speed-limit 1 --speed-time 120 so a stalled transfer gives up, --max-filesize 512 MiB.
  • install.sh: the JVM zip's listing goes through entry_outside like the tarballs, a symlink in bin/ is refused before chmod a+x bin/*, and both curl calls get the redirect rule. action/install-kiff.sh unpacks the JVM zip through its existing unpack check.
  • plan.sh: refuses a release asset whose name holds /, \, or is ./.. before writing to a file of that name.
  • README: the .sha256 beside each asset guards against a corrupt download, not a substituted one, since both come from the same release.
  • Workflows: every third-party action is pinned to a commit SHA with its version in a trailing comment (Dependabot moves both), and the six remaining checkouts in tests.yml set persist-credentials: false.

Validation: ./gradlew :cli:jvmTest passes, including the download tests against a local server with real curl; shellcheck install.sh is clean. The install and action workflows exercise the shell paths in CI.

What a review rated low, in one change:

- kiff --use made its scratch directory with createDirectories, which
  takes a directory already there under that name, and in a shared
  temporary directory that is someone else's. It is made new or not at
  all. kiff release verifies a patch in a directory of its own for the
  same reason, rather than at a name a link could be planted at.
- curl may no longer follow a redirect from https to plain http, gives
  up on a connection that has stalled for two minutes, and refuses a
  file past half a gigabyte. The installers keep the redirect rule;
  a mirror named over http, as the tests name one, is unchanged.
- install.sh checks a JVM zip's listing before unpacking it, as it
  checks a tarball's, and refuses a link in bin before the chmod that
  would follow it. The action's installer unpacks the zip through the
  same check its archives go through.
- plan.sh refuses a release asset whose name is not a file name
  before downloading to a file of that name.
- The README says what the .sha256 guards against: a corrupt
  download, not a substituted one, since both come from the release.
- Every third-party action is pinned to a commit, with its version
  beside it for Dependabot to move, and every checkout in the tests
  workflow drops its credentials.
@github-actions

Copy link
Copy Markdown

Test Results

2 108 tests  ±0   2 108 ✅ ±0   1m 40s ⏱️ -22s
  211 suites ±0       0 💤 ±0 
  211 files   ±0       0 ❌ ±0 

Results for commit d5bf824. ± Comparison against base commit 28c4439.

@linroid
linroid merged commit 8dab11e into main Oct 28, 2026
29 checks passed
@linroid
linroid deleted the fix/review-low-cli branch October 28, 2026 13:55
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