engineering/security-guidance/skills/security-guidance/SKILL.md
PreToolUse security-anti-pattern hook for Claude Code. Catches 12 common security risks (command injection, XSS, SQL injection, unsafe deserialization, GitHub Actions workflow injection, eval/new Function code injection) BEFORE the Edit/Write/MultiEdit operation completes. Session-state caching prevents duplicate warnings on the same file+rule combo. Stdlib only — no dependencies. Use when you want a safety net during Claude Code sessions that touch security-sensitive code (auth, payments, user input handling, IaC). Disable with ENABLE_SECURITY_REMINDER=0 if you need to perform a verified-safe operation that would otherwise trip a pattern. Triggers — "add security hook", "block unsafe code", "detect command injection before write", "prevent SQL injection patterns", "security warning hook".
npx skillsauth add alirezarezvani/claude-skills security-guidanceInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
A PreToolUse hook that blocks 12 common security anti-patterns before Claude Code writes them.
This skill is a hook, not a slash command. Once installed, it runs automatically before every Edit, Write, or MultiEdit operation and warns + blocks if it detects a known dangerous pattern.
The hook scans both:
${{ }} patterns| Pattern | Category | Risk |
|---|---|---|
| GitHub Actions workflow expressions | Path-based | Workflow command injection via untrusted inputs |
| child_process.exec, exec(, execSync( | Substring | Node.js command injection |
| new Function | Substring | JS code injection |
| eval( | Substring | JS code injection |
| dangerouslySetInnerHTML | Substring | React XSS |
| document.write | Substring | DOM XSS |
| .innerHTML = | Substring | DOM XSS |
| pickle | Substring | Python deserialization RCE |
| os.system, from os import system | Substring | Python command injection |
| shell=True (subprocess) | Substring | Python command injection |
| f-string SQL or .format SQL | Substring | SQL injection |
| yaml.load(, yaml.unsafe_load | Substring | YAML deserialization RCE |
Edit, Write, or MultiEditsecurity_reminder_hook.py with the tool input as JSON on stdin~/.claude/security_warnings_state_<session>.jsonThis plugin ships as a Claude Code plugin with hooks.json wiring:
# In Claude Code:
/plugin marketplace add alirezarezvani/claude-skills
/plugin install security-guidance@claude-code-skills
Once installed, no further configuration needed — the hook runs automatically.
Disable per-session via environment variable:
ENABLE_SECURITY_REMINDER=0 claude
# Hook is bypassed for this session
Use sparingly — the hook is most useful exactly when you're tempted to disable it (because you're under deadline pressure to ship something you know is sketchy).
If a specific file legitimately needs eval() or pickle (e.g., a sandboxed REPL, a deliberately unsafe parser for a fuzzer), document it in the file with a comment:
# SAFETY: pickle is the required serialization format for this internal tool.
# This file does NOT accept untrusted input. See SECURITY.md for boundary analysis.
import pickle
The hook will still warn on first edit per session. After acknowledging, subsequent edits in the same session are allowed (session-state caching).
Trade-off: AST-based detection would be more precise (no false positives on string literals containing "eval("). Substring-based is:
For 90%+ of cases, substring detection is sufficient. If you need stricter detection, layer in a proper SAST tool (semgrep, CodeQL) as a CI step.
The hook caches "warning shown" state in ~/.claude/security_warnings_state_<session_id>.json. These files:
<file_path>-<rule_name> keysYou can safely delete ~/.claude/security_warnings_state_*.json files at any time — the hook regenerates them on next run.
The hook writes to ~/.claude/security-warnings-log.txt for debugging hook misfires:
tail -f ~/.claude/security-warnings-log.txt
# Shows JSON decode errors, state-file save failures, etc.
(Upstream version wrote to /tmp/security-warnings-log.txt — we moved it to ~/.claude/ for persistence across reboots.)
This plugin is ported from David Dworken's MIT-licensed implementation in alirezarezvani/aeo-box.
Verbatim: the original 9 patterns (GitHub Actions, child_process.exec, new Function, eval, dangerouslySetInnerHTML, document.write, innerHTML, pickle, os.system) are preserved with their exact warning text.
Modifications:
subprocess shell=True, SQL injection via f-string or .format, yaml.unsafe_load/tmp/security-warnings-log.txt → ~/.claude/security-warnings-log.txtattribution block in plugin.jsonDefeats the purpose. If ENABLE_SECURITY_REMINDER=0 becomes your default, you've trained yourself to ignore the safety net. Use it only for specific verified-safe operations.
Anyone can add a pattern. Removing one requires a security review — patterns exist because they map to real CVE classes.
The cache prevents nag-spam but is per-session. Don't rely on "I dismissed this once" as long-term policy — use the per-file documentation pattern instead (comment justifying the use).
engineering-team/skills/red-team — adversarial pen-testingengineering-team/skills/threat-detection — threat modeling + detection designengineering-team/skills/ai-security — AI-specific security (prompt injection, etc.)engineering/ship-gate — pre-production audit (8-category, ~89 checks)engineering/skill-security-auditor — security scan for skill packagesVersion: 2.7.3
Source: Ported from alirezarezvani/aeo-box .claude/plugins/security-guidance/ (originally by David Dworken at Anthropic, MIT)
License: MIT
development
Use when someone wants to run a weekly review, close open loops, audit stalled projects and commitments, get their system back to trusted, restart a lapsed review habit, or says "/cs:weekly-review". Walks David Allen's three-phase loop — GET CLEAR, GET CURRENT, GET CREATIVE — with deterministic scripts that inventory open loops, gate the checklist with named gaps, and score commitment health 0-100.
development
Use when someone wants to decide whether a meeting is worth calling, price a meeting in dollars, build a timeboxed agenda with desired outcomes, or turn messy meeting notes into owned action items — or says "should this be a meeting", "/cs:meeting-prep", or "/cs:meeting-actions". Runs a cost gate (ASYNC / NOT-READY / MEET), builds a decision-first agenda, and extracts an owner + due-date checklist that flags every orphan.
development
Convert a rambling description of a desired outcome into one polished, autonomous /goal prompt ready to paste into a fresh session. Use when the user says "/fable-goal", "turn this into a goal prompt", "write me a fable prompt", "write the prompt that builds X", or rambles about something they want made and asks for the prompt that makes it happen. The output is a single copy-paste prompt, never the build itself. Do NOT use when the user wants the thing built right now in this session — only when they want the PROMPT that will make it happen in a fresh session.
development
Use when someone wants to plan a deep work day, time-block their calendar or task list, budget or cut shallow work, protect focus hours, track deep-work sessions and streaks, run an end-of-day shutdown ritual, or says "/deep-work" or "/time-block". Classifies tasks deep vs shallow, builds an energy-first time-blocked schedule that refuses deep demand past the 4-hour ceiling, batches shallow work into at most two windows, and logs focus sessions against a weekly target.