Skip to content

Stop exposing service tokens via process command-line arguments - #23

Merged
mkitti merged 2 commits into
mainfrom
fix-token-argv-exposure
Sep 10, 2026
Merged

mkitti merged 2 commits into
mainfrom
fix-token-argv-exposure

Conversation

@mkitti

@mkitti mkitti commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

A security review found that the marimo and web-terminal (ttyd) service tokens were passed as plain command-line arguments to subprocesses, which are visible to other users on the same host via ps//proc/<pid>/cmdline.

  • marimo: switch --token-password "$TOKEN" to --token-password-file <path> (marimo already supports this; both wrappers already persist the token to a file).
  • ttyd: ttyd has no env/file option for its -c user:pass Basic Auth (unimplemented upstream: Allow specifying HTTP basic auth credentials from a file tsl0922/ttyd#872), so Basic Auth is now enforced by the fronting Caddy proxy (basic_auth with a bcrypt hash, hashed via stdin so it never appears on caddy's argv either), and ttyd runs in its -H/--auth-header auth-proxy trust mode instead of -c.

Test plan

  • bash -n on all four modified scripts
  • Confirmed marimo's installed CLI supports --token-password-file
  • Live-tested caddy_hash_password + caddy_start's new basic_auth/header_up Caddyfile block against a running Caddy instance: correct credentials over HTTPS → 200, wrong credentials → 401
  • Live-tested ttyd 1.7.7 in -H auth-proxy mode: request without the trusted header → 407, with it → 200
  • End-to-end run of pixi run marimo-https and pixi run terminal-https in a real Fileglancer job, confirming no token appears in ps auxww output for either service

🤖 Generated with Claude Code

mkitti and others added 2 commits September 8, 2026 16:04
Command-line arguments are visible to other users on the same host via
ps/proc, so --token-password "$TOKEN" leaked the token. marimo already
supports --token-password-file, and both entrypoint.sh and https-wrap.sh
already persist the token to a file, so switch to that instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ttyd's own -c user:pass auth has no env-var or credential-file option
(tsl0922/ttyd#872), so the terminal token was passed on ttyd's command
line -- visible to other users on the host via ps. Caddy now performs
the Basic Auth check itself (basic_auth with a bcrypt hash generated via
stdin, never on argv) and forwards a static trust header to ttyd, which
runs in its -H/--auth-header auth-proxy mode instead of -c.

Verified live: caddy_start's generated Caddyfile enforces Basic Auth
(200 for correct creds, 401 for wrong) and ttyd in -H mode requires the
injected header (407 without it, 200 with it).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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