Skip to content

fix(upgrade): quote MOSHCODE_HOME and installer URL in the self-upgrade shell#45

Merged
ralyodio merged 1 commit into
moshcoder:mainfrom
khipu-agent:fix/upgrade-shell-quoting
Jul 26, 2026
Merged

fix(upgrade): quote MOSHCODE_HOME and installer URL in the self-upgrade shell#45
ralyodio merged 1 commit into
moshcoder:mainfrom
khipu-agent:fix/upgrade-shell-quoting

Conversation

@khipu-agent

Copy link
Copy Markdown
Contributor

Bug

selfSpec() in src/upgrade.mjs interpolated MOSHCODE_HOME and the installer URL raw inside an sh -c command line, wrapped in single quotes:

`export MOSHCODE_HOME='${MOSHCODE_HOME}'; curl -fsSL ${SELF_URL} | sh -s -- update`

Two consequences:

  1. Broken upgrade on apostrophe paths. If the install path contains a ' (e.g. /Users/o'brien/moshcode), moshcode upgrade dies with a shell syntax error:
    sh: -c: line 0: unexpected EOF while looking for matching `''
    exit code 2
    
  2. Shell injection. A path/URL value containing '…'; <cmd>; # breaks out of the quotes and runs extra shell inside the self-update command.

Repro

sh -c "export MOSHCODE_HOME='/Users/o'brien/moshcode'; echo ok"
# => unexpected EOF while looking for matching `''

Fix

  • Add shQ() — POSIX-safe single-quoting: wrap in '…', escape every ' as '\''.
  • Apply it to both MOSHCODE_HOME and the installer URL.
  • Export selfSpec(home, url) with injectable params so it is testable.

Tests

New tests in test/upgrade.test.mjs run the actual generated command with a stubbed curl on PATH:

  • an apostrophe-containing path survives the round-trip intact,
  • an injector path ('; touch /tmp/pwned; #) cannot create its marker file.

Both fail against the original code and pass with the fix. Full suite: 160/160.

…de shell

selfSpec() embedded both values raw in a `sh -c` command line. An apostrophe
in the install path (e.g. /Users/o'brien/moshcode) broke `moshcode upgrade`
with a shell syntax error, and a hostile path could break out of the quotes
and inject extra shell into the update command. POSIX single-quote escaping
(' -> '\'') fixes both; selfSpec is exported with injectable home/url so the
quoting is unit-tested end to end through a real sh.
@ralyodio
ralyodio merged commit 5029919 into moshcoder:main Jul 26, 2026
3 checks passed
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.

2 participants