Skip to content

fix(fleet): the sudo password was being executed as a command - #19

Merged
ralyodio merged 1 commit into
mainfrom
fix/sudo-password-run-as-command
Aug 30, 2026
Merged

fix(fleet): the sudo password was being executed as a command#19
ralyodio merged 1 commit into
mainfrom
fix/sudo-password-run-as-command

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Reported from the desktop, and reproducible in one line:

/bin/sh: 1: <the password>: not found

Cause

sudo -S reads the password from stdin only when it actually needs one. Under NOPASSWD, a still-valid sudo timestamp, or a login that is already root, it reads nothing at all — and the password, which was prepended to the script on the same stream, falls through to sh -es and runs as command number one. Which also puts it in an error message.

That is not a corner case. It is what happens on every deploy account configured the way deploy accounts are configured, and it is why this looked fine in review: the mechanism is correct exactly when sudo challenges you, and silently wrong when it does not.

Fix

Stop sharing the stream. With a sudo password the script now travels as a quoted argument (sh -ec '<script>') and stdin carries the password alone, so there is no ordering to get right.

  • withSudoPassword throws rather than proceeding if handed a command whose stdin is already occupied.
  • A password containing a newline is refused — it cannot be escaped, only rejected, since the newline would end the line sudo reads and hand the remainder to the command.
  • Everywhere else is untouched: with no sudo, or sudo -n, the script still goes on stdin, where nothing is quoted so nothing can be misquoted and a script is not bounded by the command-line length limit.

Also: a refused password now says so. sudo emits both Authentication failed, try again and authentication required but not attempted on a failed attempt, and matching the second told someone who had supplied a password to supply one.

Verified against real hosts

Not by reading. root@localhost has passwordless sudo — the broken case — and anthony@localhost does challenge:

Case Result
password mode, sudo wants nothing script runs, password not executed, nothing leaks to stderr
password mode, wrong password, sudo challenges refused, script does not run, password not echoed back
quotes, backticks, $VAR, pipes, redirects survive the quoted argument byte for byte
sudo off and sudo -n unchanged

Reproduced the original failure first, confirmed the fix clears it, then checked the reverse case so the fix cannot have simply disabled authentication.

Two existing tests asserted the old behaviour and were codifying the bug. They now assert the invariant instead: in password mode stdin is the password and only the password.

491 tests across 40 files, full typecheck, green.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UeSWg1Czsb2Lwxj8vHUnA4

Reported from the desktop, and reproducible in one line:

    /bin/sh: 1: <the password>: not found

`sudo -S` reads the password from stdin **only when it actually needs one**.
Under NOPASSWD, a still-valid sudo timestamp, or a login that is already
root, it reads nothing at all — and the password, which was prepended to the
script on the same stream, falls through to `sh -es` and runs as command
number one. Which also puts it in an error message.

That is not a corner case. It is what happens on every deploy account
configured the way deploy accounts are configured, and it is why the feature
looked fine in review: the mechanism is correct exactly when sudo challenges
you, and silently wrong when it does not.

The fix is to stop sharing the stream. With a sudo password the script now
travels as a quoted argument (`sh -ec '<script>'`) and stdin carries the
password alone, so there is no ordering to get right. `withSudoPassword`
throws rather than proceeding if it is ever handed a command whose stdin is
already occupied, and rejects a password containing a newline — which cannot
be escaped, only refused, since the newline would end the line sudo reads and
hand the remainder to the command.

Everywhere else is untouched: with no sudo, or `sudo -n`, the script still
goes on stdin, where nothing is quoted so nothing can be misquoted and a
script is not bounded by the command-line length limit.

Also: a refused password now says so. sudo emits both "Authentication failed,
try again" and "authentication required but not attempted" on a failed
attempt, and matching the second told someone who *had* supplied a password
to supply one.

Verified against real hosts rather than by reading, using root@localhost
(passwordless sudo, the broken case) and anthony@localhost (sudo does
challenge):

- password mode where sudo wants nothing: script runs, password is not
  executed, nothing leaks to stderr
- password mode with a WRONG password where sudo does challenge: refused, the
  script does not run, the password is not echoed back
- a script of quotes, backticks, `$VAR`, pipes and redirects survives the
  quoted argument byte for byte
- `sudo off` and `sudo -n` unchanged

Two tests asserted the old behaviour and were codifying the bug; they now
assert the invariant instead — in password mode `stdin` is the password and
only the password.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UeSWg1Czsb2Lwxj8vHUnA4
@ralyodio
ralyodio merged commit 966ae94 into main Aug 30, 2026
4 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.

1 participant