From security
Run a security assessment using deterministic static analysis tools with LLM-powered triage
npx claudepluginhub zate/cc-plugins --plugin securityThis skill is limited to using the following tools:
Run a security assessment that combines deterministic tool output with LLM-powered triage. **Every finding is labeled with its provenance: [Static] or [LLM].**
Orchestrates repo security scans (SAST, SCA, secrets, config) with adaptive agent swarms: subagents for small repos, teams for large. Verifies findings, compiles reports.
Scans local projects for dependency vulnerabilities (SCA), code security patterns (SAST), leaked secrets, auth/crypto flaws, misconfigs, supply chain risks, CI/CD issues. Generates prioritized report with remediation guidance.
Runs parallel Semgrep scans on multi-language codebases with full or security-focused modes. Auto-uses Pro for taint analysis; merges SARIF output.
Share bugs, ideas, or general feedback.
Run a security assessment that combines deterministic tool output with LLM-powered triage. Every finding is labeled with its provenance: [Static] or [LLM].
"${CLAUDE_PLUGIN_ROOT}/scripts/detect-tools.sh"
Display capability report:
/security:setup but continue (regex scan always works)"${CLAUDE_PLUGIN_ROOT}/scripts/recon.sh"
Display detected stack: languages, frameworks, package managers, infrastructure.
From $ARGUMENTS:
--quick: Fast scan, skip triage, 10-finding budget--deep: Thorough scan, 50-finding budget--diff: Scan only files changed vs main branch (or --diff-base <ref>)--path <dir>: Scope scan to specific directory (default: project root)--suppress <id>: Add a finding to suppressions.json and re-display report--show-suppressed: Include suppressed findings in report outputIf --suppress <id>: Add the finding to .security/suppressions.json, then redisplay the last report excluding the suppressed finding. Do NOT re-run the scan. STOP after updating.
If --diff:
"${CLAUDE_PLUGIN_ROOT}/scripts/get-changed-files.sh"
Use the output to scope scanners to changed files only. If no files changed, report "No changed files to scan" and STOP.
Run all available scanners. Show progress as each completes.
"${CLAUDE_PLUGIN_ROOT}/scripts/run-scanners.sh" [--path <dir>]
This runs whichever tools are installed (semgrep, gitleaks, trivy, bandit, gosec) and writes normalized output to .security/artifacts/.
"${CLAUDE_PLUGIN_ROOT}/scripts/run-regex-scan.sh" [--path <dir>]
Pattern-based detection for common vulnerabilities. Always available regardless of installed tools. Output goes to .security/artifacts/.
Show after each scanner completes:
[+] semgrep: 12 findings (completed in 8s)
[+] gitleaks: 3 findings (completed in 2s)
[+] regex-scan: 7 findings (completed in 1s)
"${CLAUDE_PLUGIN_ROOT}/scripts/correlate.sh"
Deduplicate findings across tools. Same file + same line + same CWE = single finding with multiple sources.
Display: "X unique findings after deduplication (from Y raw findings across Z tools)"
If zero findings: Congratulate the user, show coverage estimate, suggest /security:scan --deep if they ran standard mode. STOP here.
If --quick: Skip triage entirely. Report raw tool findings directly. Jump to Phase 4.
Otherwise: Triage findings yourself using the decision tree below. Do NOT delegate to the triage-agent for standard scans -- do the work directly. Only use the triage-agent for --deep scans with 50+ findings.
Read .security/correlated.json.
For each finding, read exactly 5 lines of context around the flagged line, then apply:
| Framework | CWE | Protection | Bypass Indicators |
|---|---|---|---|
| Django | CWE-89 | ORM parameterizes | .raw(), .extra(), cursor() |
| Django | CWE-79 | Template auto-escape | |safe, mark_safe() |
| SQLAlchemy | CWE-89 | ORM parameterizes | text() with f-string |
| React | CWE-79 | JSX auto-escapes | dangerouslySetInnerHTML |
| Rails | CWE-89 | AR parameterizes | find_by_sql(), execute() |
| CWE | Base | Upgrade condition | Downgrade condition |
|---|---|---|---|
| CWE-78 | CRITICAL | -- | CLI tool: HIGH |
| CWE-89 | HIGH | Public unauth endpoint: CRITICAL | Internal: MEDIUM |
| CWE-79 | HIGH | Stored XSS: CRITICAL | Self-XSS: LOW |
| CWE-798 | CRITICAL | Production keys | Dev/staging: HIGH |
| CWE-502 | CRITICAL | Network input | Local cache: MEDIUM |
| Other | MEDIUM | Public endpoint: HIGH | Test/internal: LOW |
TRUE_POSITIVE: [What]. [Why exploitable]. [What input reaches sink].
FALSE_POSITIVE: [Rule that fired]. [Why it is FP -- cite protection].
NEEDS_REVIEW: [What flagged]. [Why indeterminate]. [What to check].
Replace [vulnerable pattern] with [secure pattern]. Example: [one-line code].
One fix only. Do not offer alternatives.
Enforce maximum findings in the report:
--quick: 10 findings max--deep: 50 findings maxIf over budget, keep highest severity findings and note how many were trimmed.
Generate the final report and save to .security/report.md.
# Security Scan Report
**Date:** [timestamp]
**Mode:** [quick/standard/deep]
**Scope:** [path or "full project"]
## Summary
| Severity | Count |
|----------|-------|
| CRITICAL | N |
| HIGH | N |
| MEDIUM | N |
| LOW | N |
## Tools
| Tool | Version | Findings | Status |
|------|---------|----------|--------|
| semgrep | X.Y.Z | N | ran |
| gitleaks | X.Y.Z | N | ran |
| regex-scan | built-in | N | ran |
| bandit | - | - | not installed |
## Findings
### [CRITICAL] CWE-89: SQL Injection in auth/login.py:42
**Provenance:** [Static: semgrep]
**Severity:** CRITICAL (upgraded: public endpoint)
User input from request parameter `username` reaches SQL query without parameterization.
**Code:**
\`\`\`python
cursor.execute(f"SELECT * FROM users WHERE name = '{username}'")
\`\`\`
**Remediation:** Use parameterized queries:
\`\`\`python
cursor.execute("SELECT * FROM users WHERE name = %s", (username,))
\`\`\`
---
[... more findings ...]
## Suppressed False Positives
<details>
<summary>N findings classified as false positives (click to expand)</summary>
- CWE-798 in tests/conftest.py:15 — Test fixture, not a real credential [Static: gitleaks]
- CWE-79 in templates/index.html:8 — Django auto-escaping active [Static: semgrep]
</details>
## Coverage Gaps
- **gosec not installed:** Go source files not scanned for Go-specific vulnerabilities
- **trivy not installed:** Container images and IaC not scanned
Run `/security:setup` to install missing tools.
### [SEVERITY] CWE-NNN: Title -- file:line**Provenance:** [Static: toolname1, toolname2]- CWE-NNN in file:line -- reason [Static: tool]Save the report:
mkdir -p .security
Write report to .security/report.md.
Display the full report in conversation.
AskUserQuestion:
questions:
- question: "What would you like to do next?"
header: "Scan Complete"
multiSelect: false
options:
- label: "Fix critical findings"
description: "Address CRITICAL and HIGH severity issues"
- label: "Override triage decisions"
description: "Review and change TRUE/FALSE positive classifications"
- label: "Run deeper scan"
description: "Re-scan with --deep for more thorough analysis"
- label: "Export report"
description: "Save report for sharing"
- label: "Done"
description: "No further action needed"
Route responses:
--deep flag.security/report.md/security:scan # Standard scan (default)
/security:scan --quick # Fast scan, no triage
/security:scan --deep # Thorough scan, 50-finding budget
/security:scan --diff # Scan only changed files vs main
/security:scan --diff-base HEAD~3 # Scan changes from last 3 commits
/security:scan --path src/api # Scan specific directory
/security:scan --suppress finding-003 # Suppress a false positive permanently
/security:scan --show-suppressed # Include suppressed in report
Now: Begin Phase 0 recon.