Skip to content

fix: don't allocate a remote PTY for piped stdin in machine run --shell (#4536)#4947

Draft
kylemclaren wants to merge 1 commit into
masterfrom
fix/issue-4536
Draft

fix: don't allocate a remote PTY for piped stdin in machine run --shell (#4536)#4947
kylemclaren wants to merge 1 commit into
masterfrom
fix/issue-4536

Conversation

@kylemclaren

@kylemclaren kylemclaren commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Fixes #4536.

fly machine run --shell --command <cmd> always requested a remote PTY. When stdin is piped (non-TTY), the remote terminal's line discipline echoes that piped input back to the local terminal — which can leak secrets, e.g. echo TOKEN=… | fly machine run … --shell.

A remote PTY is now requested only when one was asked for and stdin is an actual terminal (the same gating fly ssh console uses); with a fixed --command, no PTY is allocated.

Testing: added unit tests for the PTY-gating helpers (wantPTY, getFd) in ssh/; they don't build/pass on master (the gating didn't exist) and pass with the fix. go test ./ssh/... ./internal/command/machine/... is green. The stray echo itself is a non-deterministic race, so the tests cover the gating logic rather than a flaky behavioral repro.


Live-verified against a real org (over WireGuard; ephemeral machines auto-destroyed):

  • Latest flyctl (master): echo TEST=123 | fly machine run debian --shell --command "echo test" leaked TEST=123 to stdout on 8/8 runs.
  • This branch: same piped command → 0 leaks across runs (only test printed). The fix is structural — it refuses a remote PTY when stdin isn't a terminal.

🤖 Generated with Claude Code

…ll (#4536)

`fly machine run --shell` hardcoded allocPTY=true when opening the SSH
session, so a remote pseudo-terminal was requested even for a fixed
`--command` with piped, non-TTY stdin. The remote terminal line
discipline then echoed the piped bytes back, racily exposing secrets.

Mirror the gating used by `fly ssh console`: only allocate a PTY for an
interactive shell (empty --command). Also harden ssh/io.go so a PTY is
never requested unless stdin is an actual terminal, regardless of the
caller's AllocPTY value, and add a unit test covering the decision.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kylemclaren kylemclaren marked this pull request as draft June 30, 2026 14:00
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.

Machine run is inconsistently printing data from stdin

1 participant