credential-leakmajorverifiedfirsthand

A shell one-liner meant to check whether an API key was set, without revealing it, printed the entire key to the screen and the session transcript instead.

2026-09-16 · severity 7/10 · blast radius: data · tags: shell, bash, secrets, ai-coding

Cause: The expression ${VAR:+set}${VAR:-unset} was written on the belief that it would always print one of the two status words and nothing else. In fact :- returns its fallback only when the variable is unset — when the variable IS set, it expands to the variable's actual value, not a placeholder.

Consequence: The full API key was printed to both the terminal and the session log, requiring an immediate rotation.

Fix: To check presence only, use [[ -n "$VAR" ]]. To show a length, use ${#VAR}. To show just enough to identify which key it is, use the last few characters: ${VAR: -4}. Before running any command that might touch a secret, read the expression once and ask: could this print the value?

What happened

While working with an AI coding agent in a shell session, a quick check for “is this API key set?” was written as ${VAR:+set}${VAR:-unset}. It printed the key itself.

The chaos on the ground

The check looked reasonable at a glance and the “test” appeared to pass — nothing about the output looked like an error. The leak wasn’t caught by any automated check; it was caught by someone actually reading the terminal output.

Root cause

${VAR:-fallback} returns fallback only when VAR is unset or empty. When VAR is set, it expands to VAR’s actual value — not a placeholder, not a masked version, the value itself. The expression was written expecting the opposite behavior: that it would only ever show a status word, never the secret it was checking for.

The fix

For presence checks, use [[ -n "$VAR" ]] && echo present || echo absent — this never expands the variable into output. For identification without full exposure, use a length (${#VAR}) or a short trailing slice (${VAR: -4}), matching the granularity a UI would normally show. Before running any shell expression that touches a secret, read it once and ask directly: under what conditions does this print the value?

Related: