Skip to content

fix: address RUSH-594 P0 audit issues - #27

Closed
muqsitnawaz wants to merge 2 commits into
mainfrom
rush-594-p0-audit
Closed

fix: address RUSH-594 P0 audit issues#27
muqsitnawaz wants to merge 2 commits into
mainfrom
rush-594-p0-audit

Conversation

@muqsitnawaz

@muqsitnawaz muqsitnawaz commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fixes the RUSH-594 P0 code issues by writing config files with private permissions, moving issue filters and lookups to GraphQL variables, and pinning/checksum-verifying the installer download.
  • Corrects the README P0 issues by reducing the badge wall, promoting manual install over pipe-to-shell, pinning install URLs, and removing repeated/stale size and supply-chain claims.

Key Evidence

  • Config writes now create ~/.linear-cli with 0700 and config.json with 0600: linear:74, linear:75, linear:78, linear:83.
  • Issue listing now passes IssueFilter through variables instead of interpolated query text: linear:876, linear:886, linear:893, with callers building dict filters at linear:1202 and linear:1347.
  • Direct issue lookups now use $filter variables: linear:705, linear:711, linear:1422, linear:1442.
  • Installer pins v0.13.0 and verifies SHA-256 before moving into place: install.sh:7, install.sh:8, install.sh:27, install.sh:47.
  • README keeps only License/Python badges and demotes pipe-to-shell behind pinned manual install: README.md:5, README.md:6, README.md:24, README.md:31.

Verification

  • python3 -m unittest -v -> 27 tests passed.
  • python3 -m py_compile linear test_linear.py && ./linear --version && sh -n install.sh && git diff --check -> linear-cli 0.13.0, no errors.
  • Isolated installer run: HOME=/tmp/linear-install-home-U3WcTL sh install.sh; installed /tmp/linear-install-home-U3WcTL/.local/bin/linear, linear-cli 0.13.0, SHA-256 d62ee380d5565e483f0750ded837b5d453fcc380ffab14fe1d34249d2079a1c2.

Linear: RUSH-594

@muqsitnawaz muqsitnawaz changed the title WIP: fix RUSH-594 P0 audit issues fix: address RUSH-594 P0 audit issues Jul 21, 2026
@muqsitnawaz
muqsitnawaz marked this pull request as ready for review July 21, 2026 21:27
Comment thread install.sh
BRANCH="${LINEAR_CLI_BRANCH:-main}"
URL="https://raw.githubusercontent.com/${REPO}/${BRANCH}/linear"
VERSION="${LINEAR_CLI_VERSION:-v0.13.0}"
EXPECTED_SHA256="${LINEAR_CLI_SHA256:-d62ee380d5565e483f0750ded837b5d453fcc380ffab14fe1d34249d2079a1c2}"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 blocking: the checksum-pinned install path still ships the pre-fix, vulnerable script.

EXPECTED_SHA256 here is d62ee380d5565e483f0750ded837b5d453fcc380ffab14fe1d34249d2079a1c2. I fetched the actual linear blob at the v0.13.0 tag (ref=fd1adff48bc1a8c1feccd05389736c73406dc7d3, which is this PR's own base commit) and its SHA-256 is exactly that hash — confirmed with shasum -a 256 linear_v0130.pyd62ee380d5565e483f0750ded837b5d453fcc380ffab14fe1d34249d2079a1c2.

That v0.13.0-tagged file still has the pre-fix code this PR is supposed to remove:

  • 6 unsafe f-string-interpolated GraphQL query blocks (grep -n 'f"""' linear_v0130.py → lines 380, 390, 689, 871, 1409, 1724, vs. only 1 (safe, non-user-data) f-string left at linear:886 in this PR's HEAD).
  • No CONFIG_DIR_MODE/write_config_file at all (grep -n 'CONFIG_DIR_MODE\|write_config_file' linear_v0130.py → no matches).

Since __version__ is not bumped in this PR (linear still declares __version__ = "0.13.0" at HEAD) and no new tag is cut here, curl ... install.sh | sh (default LINEAR_CLI_VERSION=v0.13.0) will keep downloading and correctly verifying the checksum of the unfixed script after this PR merges. The PR body's own "Isolated installer run" verification (linear-cli 0.13.0, same SHA) is actually evidence of this: it can't distinguish fixed vs. unfixed since the version string and checksum are identical either way.

This needs a new tag (e.g. v0.14.0) cut from this PR's HEAD, with VERSION/EXPECTED_SHA256 here (and the README links) repointed to it — otherwise this P0 fix never reaches anyone who installs via the documented path.

Comment thread README.md

```bash
curl -sSL https://raw.githubusercontent.com/phnx-labs/linear-cli/main/install.sh | bash
curl -fL -o /usr/local/bin/linear https://raw.githubusercontent.com/phnx-labs/linear-cli/v0.13.0/linear

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same root cause as the install.sh:8 comment: this manual-install curl pulls linear from the v0.13.0 git tag, which is this PR's own base commit (fd1adff4) — i.e. the pre-fix script, still containing the f-string-interpolated GraphQL filters (team_id, identifier lookups) this PR is meant to close. Until a new tag is cut from this PR's HEAD and this URL (and the install.sh one two lines below) is repointed to it, following this README instruction after merge still installs the vulnerable binary.

Comment thread linear
@@ -63,19 +65,29 @@ def load_config() -> dict:
return json.loads(CONFIG_PATH.read_text())

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking, but worth tracking: permission hardening only applies on write. load_config() reads CONFIG_PATH as-is (return json.loads(CONFIG_PATH.read_text())) with no chmod — so an existing user upgrading from a pre-fix install, whose ~/.linear-cli/config.json already exists with loose (e.g. default-umask 0644) permissions and a plaintext API key, stays that way until the next save_config() call (e.g. after setup/update), not immediately on upgrade.

Also, the legacy-migration branch a few lines below (write_config_file(cfg) at what is now linear:69) writes the new ~/.linear-cli/config.json with correct 0600/0700 perms, but never touches or removes the old ~/.agents/linear.json it just read from — that file keeps holding the same plaintext API key at its original (unhardened) permissions indefinitely.

Suggest a one-time perms fix-up (chmod on existing CONFIG_PATH/parent at the top of load_config) and cleaning up (or at least chmod-ing) the legacy file post-migration, so the P0 fix actually protects users who are upgrading, not just fresh installs.

@muqsitnawaz

Copy link
Copy Markdown
Contributor Author

Git-review routine — changes requested (blocking). The security fixes in this diff are genuine (GraphQL filter injection closed, config now 0700/0600), but the delivery ships the OLD vulnerable script:

  1. install.sh:8 pins the pre-fix checksum. EXPECTED_SHA256=…d62ee380… is the SHA-256 of the linear blob at the v0.13.0 tag (this PR base fd1adff), which still has 6 f-string-interpolated GraphQL blocks and no write_config_file. __version__ stays 0.13.0 and no new tag is cut, so curl … install.sh | sh keeps serving the unfixed script — with a checksum that "verifies". fix: address RUSH-594 P0 audit issues #27 (comment)
  2. README.md:27,34 curl/manual-install both point at the pre-fix v0.13.0 tag. fix: address RUSH-594 P0 audit issues #27 (comment)
  3. Non-blocking: linear:65 read/upgrade path never chmods an existing loose config.json, and the legacy ~/.agents/linear.json plaintext key is never removed/hardened. fix: address RUSH-594 P0 audit issues #27 (comment)

To ship the fix: bump the version, cut+push a new tag on the fixed commit, recompute the installer checksum, and point README/install.sh at the new tag. Not merged.

@muqsitnawaz

Copy link
Copy Markdown
Contributor Author

Superseded for the remaining security scope (config 0600 + install pin/checksum) by #32 — fresh branch off current main (0.16.1). This PR conflicts with main and still pins pre-fix v0.13.0. Prefer landing #32; close this after that merges.

@muqsitnawaz

Copy link
Copy Markdown
Contributor Author

Superseded by #32 (merged).

PR #32 lands the remaining RUSH-2285 / RUSH-594 security P0s on current main at 0.16.1:

  • config dir 0700 / file 0600 + harden-on-load
  • install.sh pin + SHA-256 fail-closed

This PR (#27) was conflicted and still pinned pre-fix v0.13.0 plus broader README/GraphQL scope. Closing as superseded; security half is on main via #32.

@muqsitnawaz

Copy link
Copy Markdown
Contributor Author

Closing as superseded by merged #32 (RUSH-2285).

@muqsitnawaz muqsitnawaz closed this Aug 6, 2026
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