Skip to content

Commit 9e4cef2

Browse files
sjnimsclaude
andauthored
docs: document [BANG] security workaround for Claude Code #12781 (#156)
## Description Document the `[BANG]` placeholder security workaround used in skill documentation to prevent unintended shell execution during skill loading. ## Type of Change - [ ] Bug fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [x] Documentation update (improvements to README, CLAUDE.md, or component docs) - [ ] Refactoring (code change that neither fixes a bug nor adds a feature) - [ ] Configuration change (changes to .markdownlint.json, plugin.json, etc.) ## Component(s) Affected - [ ] Commands (`/plugin-dev:*`) - [x] Skills (methodology and best practices) - [ ] Agents (requirements-assistant) - [ ] Hooks (UserPromptSubmit) - [x] Documentation (README.md, CLAUDE.md, SECURITY.md) - [ ] Configuration (.markdownlint.json, plugin.json, marketplace.json) - [ ] Issue/PR templates - [ ] Other (please specify): ## Motivation and Context The plugin uses a `[BANG]` placeholder to prevent [Claude Code issue #12781](anthropics/claude-code#12781) where inline bash patterns in fenced code blocks can execute during skill loading. This workaround was implemented in PR #142 but never documented, risking future maintainers accidentally reverting it. Fixes #151 ## Solution Added comprehensive documentation explaining: - What the vulnerability is - Why `[BANG]` is used instead of `!` - How to audit for unescaped patterns - Reference to the original fix (PR #142) ### Changes - **SECURITY.md**: Added "Known Security Mitigations" section with full explanation, audit command, and maintainer guidance - **CONTRIBUTING.md**: Added "Shell Pattern Escaping" subsection to Markdown Style guidelines - **testing-strategies.md**: Fixed unescaped `!`` pattern using hex escape (`\x60`) to avoid triggering the bug ### Alternatives Considered 1. **Just add a comment in CHANGELOG**: Insufficient - future maintainers may not read changelog 2. **Add CI check**: Good idea but out of scope - could be follow-up work ## How Has This Been Tested? **Test Configuration**: - Claude Code version: Latest - GitHub CLI version: 2.x - OS: macOS **Test Steps**: 1. Verified no unescaped patterns remain: `grep -rn '!`' plugins/plugin-dev/skills/ --include='*.md' | grep -v '\[BANG\]' | grep -v '\\x60'` 2. Ran markdownlint on all modified files - passes 3. Verified links in SECURITY.md point to correct anchors ## Checklist ### General - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas (if applicable) - [x] My changes generate no new warnings or errors ### Documentation - [x] I have updated the documentation accordingly (README.md, CLAUDE.md, or component docs) - [ ] I have updated YAML frontmatter (if applicable) - [x] I have verified all links work correctly ### Markdown - [x] I have run `markdownlint` and fixed all issues - [x] My markdown follows the repository style (ATX headers, dash lists, fenced code blocks) - [ ] I have verified special HTML elements are properly closed (`<example>`, `<commentary>`, etc.) ### Testing - [x] I have tested the plugin locally with `cc --plugin-dir plugins/plugin-dev` - [ ] I have tested the full workflow (if applicable) - [ ] I have verified GitHub CLI integration works (if applicable) - [ ] I have tested in a clean repository (not my development repo) ### Version Management (if applicable) - [ ] I have updated version numbers in both `plugin.json` and `marketplace.json` (if this is a release) - [ ] I have updated CHANGELOG.md with relevant changes ## Reviewer Notes **Areas that need special attention**: - Verify the hex escape `\x60` in testing-strategies.md works correctly - Confirm SECURITY.md anchor link works from CONTRIBUTING.md **Known limitations or trade-offs**: - Does not add CI check to prevent reintroduction (could be follow-up issue) --- 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
1 parent e729b17 commit 9e4cef2

3 files changed

Lines changed: 49 additions & 3 deletions

File tree

CONTRIBUTING.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,23 @@ markdownlint '**/*.md' --ignore node_modules --fix
150150
- No line length limits
151151
- Allowed HTML: `<p>`, `<img>`, `<example>`, `<commentary>`
152152

153+
### Shell Pattern Escaping
154+
155+
When documenting bash execution patterns in skill files, use `[BANG]` instead of `!` to prevent unintended execution during skill loading ([Claude Code #12781](https://github.com/anthropics/claude-code/issues/12781)).
156+
157+
```markdown
158+
<!-- In skill documentation (SKILL.md, references/, examples/) -->
159+
Current branch: [BANG]`git branch --show-current`
160+
161+
<!-- The [BANG] placeholder prevents execution while loading -->
162+
```
163+
164+
**Important**:
165+
166+
- This applies to skill files that get loaded into context
167+
- Command files (`.claude/commands/*.md`) use actual `!` syntax
168+
- See [SECURITY.md](SECURITY.md#shell-pattern-escaping-with-bang-placeholder) for full details
169+
153170
## Component-Specific Guidelines
154171

155172
### Commands (`/plugin-dev:*`)

SECURITY.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,34 @@ When a security vulnerability is confirmed:
7272
4. **Markdown Linting**: Run `markdownlint` before committing to catch potential issues
7373
5. **Test Locally**: Always test with `cc --plugin-dir plugins/plugin-dev` before pushing
7474

75+
## Known Security Mitigations
76+
77+
### Shell Pattern Escaping with [BANG] Placeholder
78+
79+
**Issue**: [Claude Code #12781](https://github.com/anthropics/claude-code/issues/12781)
80+
81+
Due to a Claude Code issue, inline bash execution patterns (exclamation mark followed by backtick) inside fenced code blocks can be executed when skills are loaded—even when they appear as documentation examples.
82+
83+
**Mitigation**: This plugin uses a `[BANG]` placeholder instead of `!` in skill documentation that shows bash execution patterns.
84+
85+
```markdown
86+
<!-- UNSAFE - may execute during skill load -->
87+
Current branch: !`git branch --show-current`
88+
89+
<!-- SAFE - displays as documentation only -->
90+
Current branch: [BANG]`git branch --show-current`
91+
```
92+
93+
**For maintainers**:
94+
95+
- Do NOT "fix" `[BANG]` back to `!` - this is intentional
96+
- When adding new documentation with bash patterns, use `[BANG]`
97+
- Audit command: `grep -rn '!`' plugins/plugin-dev/skills/ --include='*.md' | grep -v '\[BANG\]'`
98+
- See [CONTRIBUTING.md](CONTRIBUTING.md) for documentation guidelines
99+
- Reference: [command-development skill](plugins/plugin-dev/skills/command-development/SKILL.md) lines 340-378
100+
101+
**History**: Fixed in PR #142 (v0.2.0)
102+
75103
## Scope
76104

77105
This security policy applies to:
@@ -125,4 +153,4 @@ _No security issues have been reported yet._
125153

126154
---
127155

128-
**Note:** _This security policy was last updated: December 7, 2025_
156+
**Note:** _This security policy was last updated: December 13, 2025_

plugins/plugin-dev/skills/command-development/references/testing-strategies.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -676,8 +676,9 @@ echo "Test: \$1 and \$2" > .claude/commands/test-args.md
676676
# Check allowed-tools
677677
grep "allowed-tools" .claude/commands/my-command.md
678678

679-
# Verify command syntax
680-
grep '!`' .claude/commands/my-command.md
679+
# Verify command has bash execution syntax (! followed by backtick)
680+
# Note: Command files use actual ! syntax, not [BANG] placeholder
681+
grep -E '!\x60' .claude/commands/my-command.md
681682

682683
# Test command manually
683684
date

0 commit comments

Comments
 (0)