agentsclimarketplace

Security scan

Skill claude-hangar/claude-hangar/core/skills/security-scan

Production-grade configuration management for Claude Code. Hooks, agents, skills, multi-project orchestration.

Install
npx -y skills add claude-hangar/claude-hangar --skill security-scan

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Security scan for Claude Code projects (secrets, MCP permissions, hook safety, dependencies). Use when: "security scan", "check security", "is this secure", "before deploy security", "scan for secrets".

SKILL.md

17.1 KB, as published. Nobody here has run it

<!-- AI-QUICK-REF ## /security-scan — Quick Reference - **Modes:** scan (all) | secrets | mcp | hooks | deps | config - **Arguments:** `/security-scan $0` e.g. `/security-scan`, `/security-scan mcp` - **5 Phases:** Secret Detection, MCP Audit, Hook Safety, Dependency Audit, Config Review - **Finding-IDs:** SEC-S-01 (secrets), SEC-M-01 (MCP), SEC-H-01 (hooks), SEC-D-01 (deps), SEC-C-01 (config) - **Severity:** CRITICAL > HIGH > MEDIUM > LOW > INFO - **Grade:** A-F based on weighted findings - **State:** .security-scan-state.json - **Read-only:** Never modifies project files -->

/security-scan — Security Scan

Security scanner for Claude Code projects. Checks for hardcoded secrets, MCP server permissions, hook safety, dependency vulnerabilities, and configuration anti-patterns. Read-only — analyzes but never modifies.

Problem

Claude Code projects have a unique attack surface: MCP servers with broad permissions, hook scripts that execute automatically, and configuration files that can disable safety checks. Standard security scanners miss these Claude Code-specific vectors entirely.


Modes

ModeTriggerScope
scan/security-scan (default)All 5 phases
secrets/security-scan secretsPhase 1 only
mcp/security-scan mcpPhase 2 only
hooks/security-scan hooksPhase 3 only
deps/security-scan depsPhase 4 only
config/security-scan configPhase 5 only

Phase 1: Secret Detection

Scan for hardcoded secrets in source files, configs, and environment handling.

1.1 Hardcoded Secret Patterns

Search all tracked files (respect .gitignore) for these pattern categories.

NOTE: Use the same detection patterns defined in the project's secret-leak-check.sh hook as a baseline. The hook file is the canonical source of secret patterns — do not duplicate regexes here. Instead, reference the hook and add these additional categories:

CategoryWhat to detectSeverity
Cloud provider access keysAWS key ID prefixes, cloud secret key assignmentsCRITICAL
Generic API keysVariables named api_key/apikey assigned string values 20+ charsHIGH
Generic secretsVariables named secret/passwd assigned non-placeholder values 8+ charsHIGH
Private keysPEM-format private key headers (RSA, EC, DSA, OPENSSH)CRITICAL
Platform tokensGitHub ghp_/gho_/ghs_/ghr_ prefixed tokens, Slack xox* prefixed tokensCRITICAL/HIGH
JWTsBase64url-encoded three-segment eyJ... stringsMEDIUM
Connection stringsDatabase URIs with embedded credentials (user:pass@host format)CRITICAL
Bearer tokensLiteral bearer token values in codeHIGH

Exclusions: Skip node_modules/, .git/, dist/, build/, lock files, and binary files. Skip patterns inside comments that are clearly examples (e.g. YOUR_KEY_HERE, xxx, changeme).

Finding: SEC-S-{NN}: Hardcoded {type} found in {file}:{line}

1.2 Environment File Safety

CheckPassFail
.env in .gitignore.gitignore contains .env patternMissing — CRITICAL
.env not committedgit ls-files .env returns empty.env is tracked — CRITICAL
.env.example existsFile present with placeholder valuesMissing — LOW
.env.local in .gitignorePattern presentMissing — MEDIUM

Finding: SEC-S-{NN}: {description}

1.3 Gitignore Completeness

Check .gitignore for these security-relevant patterns:

PatternPurposeSeverity if missing
.envEnvironment variablesCRITICAL
*.pem / *.keyPrivate keysHIGH
.claude/credentials*Claude credentialsHIGH
*.sqlite / *.dbLocal databasesMEDIUM
.security-scan-state.jsonScan stateINFO

Finding: SEC-S-{NN}: .gitignore missing pattern for {pattern}


Phase 2: MCP Server Audit

Analyze MCP server configurations for permission and trust issues.

2.1 Locate MCP Config

Read MCP server configs from these locations (in priority order):

  1. .claude/settings.json (project-level)
  2. ~/.claude/settings.json (user-level)

Parse with node -e (cross-platform). Extract mcpServers object.

2.2 Permission Analysis

For each MCP server, check:

CheckConditionSeverity
File system accessServer has filesystem or fs capabilitiesHIGH
Network accessServer has fetch, http, or network capabilitiesHIGH
Shell executionServer can run bash, exec, or commandCRITICAL
Broad permissionsServer has * or all in permission listCRITICAL
Write permissionsServer has write access to project filesMEDIUM

Finding: SEC-M-{NN}: MCP server "{name}" has {permission} — {risk description}

2.3 Trust Assessment

CheckConditionSeverity
Unknown sourceServer not from npm/official registry, no GitHub linkHIGH
No version pinningServer uses latest or unpinned versionMEDIUM
Local file serverServer points to local script (check script exists and content)MEDIUM
Excessive server countMore than 10 MCP servers configuredLOW

Finding: SEC-M-{NN}: {description}

2.4 Known Safe Servers

Maintain a list of recognized MCP servers (do not flag these as unknown):

  • @anthropic-ai/* — Official Anthropic servers
  • @modelcontextprotocol/* — Official MCP servers
  • playwright — Browser automation
  • github — GitHub integration
  • context7 — Documentation lookup

Servers not on this list get an INFO finding, not automatic HIGH.


Phase 3: Hook Safety

Analyze hook scripts for dangerous patterns that could indicate supply-chain attacks or accidental security holes.

3.1 Locate Hooks

Search for hook definitions in:

  1. .claude/settings.json > hooks object
  2. .claude/hooks/ directory (all .sh, .js, .mjs files)

3.2 Dangerous Patterns

Scan each hook script/command for:

PatternWhat to look forSeverityRationale
eval usageThe eval keyword in shell/JSHIGHArbitrary code execution
exec with variableexec followed by unresolved variableHIGHCommand injection
Unquoted variablesShell variables expanded without quotesMEDIUMWord splitting, globbing
curl to external hostcurl targeting non-localhost URLsHIGHData exfiltration
wget to external hostwget targeting non-localhost URLsHIGHData exfiltration
Base64 decode piped to shellDecoded base64 piped into bash/sh/nodeCRITICALObfuscated payload
Network send with datacurl/wget with POST data flagsCRITICALData exfiltration
Environment dumpingCommands that dump all env vars to fileHIGHCredential leak
Write to system dirsWrites to /usr/bin/, /usr/sbin/, etc.HIGHSystem modification
Download and executecurl/wget piped directly into shellCRITICALRemote code execution

Finding: SEC-H-{NN}: Hook "{name}" contains {pattern} — {risk}

3.3 Hook Structure Checks

CheckPassFail
Uses node -e for JSON parsingCorrect patternUses jq or custom parsing — INFO
Hook has clear purposeDescriptive name/commentUnnamed or obfuscated — LOW
Hook modifies filesAcceptable if documentedUndocumented modification — MEDIUM
Hook runs external commandsAcceptable if localCalls external services — HIGH

Finding: SEC-H-{NN}: {description}


Phase 4: Dependency Audit

Check project dependencies for known vulnerabilities and risk signals.

4.1 npm Audit (if applicable)

If package.json exists:

npm audit --json 2>/dev/null | node -e "
  const data = JSON.parse(require('fs').readFileSync(0,'utf8'));
  const meta = data.metadata || {};
  const vulns = meta.vulnerabilities || {};
  console.log(JSON.stringify({
    total: meta.totalDependencies || 0,
    critical: vulns.critical || 0,
    high: vulns.high || 0,
    moderate: vulns.moderate || 0,
    low: vulns.low || 0
  }));
"

Map results to findings:

npm severityScan severityFinding
criticalCRITICALSEC-D-{NN}: {count} critical vulnerabilities in dependencies
highHIGHSEC-D-{NN}: {count} high vulnerabilities in dependencies
moderateMEDIUMSEC-D-{NN}: {count} moderate vulnerabilities in dependencies
lowLOWSEC-D-{NN}: {count} low vulnerabilities in dependencies

If npm audit is unavailable or fails, note it as INFO and continue.

4.2 Dependency Risk Signals

Check package.json for:

CheckConditionSeverity
No lock fileNeither package-lock.json nor yarn.lock nor pnpm-lock.yamlHIGH
Wildcard versions"*" or "" in dependency versionsHIGH
Git dependencies"dep": "git+..." or "dep": "github:..."MEDIUM
File dependencies"dep": "file:..."MEDIUM
Excessive dependencies>100 direct dependencies in a single package.jsonLOW
No dev/prod separationAll deps in dependencies, none in devDependenciesLOW

Finding: SEC-D-{NN}: {description}

4.3 Python Audit (if applicable)

If requirements.txt or pyproject.toml exists:

  • Check for pinned versions (== vs >=)
  • Flag unpinned dependencies as MEDIUM
  • If pip-audit is available, run it

4.4 Outdated Major Versions

If package.json exists, check for major version staleness:

npm outdated --json 2>/dev/null | node -e "
  const data = JSON.parse(require('fs').readFileSync(0,'utf8'));
  Object.entries(data).forEach(([pkg, info]) => {
    const curr = (info.current || '').split('.')[0];
    const latest = (info.latest || '').split('.')[0];
    if (curr && latest && curr !== latest) {
      console.log(pkg + ': ' + info.current + ' -> ' + info.latest);
    }
  });
"

Finding: SEC-D-{NN}: {package} is {N} major versions behind ({current} -> {latest}) — LOW


Phase 5: Configuration Review

Check Claude Code and project configuration for security anti-patterns.

5.1 CLAUDE.md Security Review

Read project CLAUDE.md (if present) and flag:

PatternWhat to look forSeverity
Disabled checksInstructions to skip/disable/ignore/bypass security, auth, or validationHIGH
Force push instructionsMentions of force push, --force, or --no-verifyMEDIUM
Hardcoded credentialsSame categories as Phase 1CRITICAL
Overly permissive instructions"always approve", "auto-approve", "no review needed"HIGH
Debug modeDebug or development mode enabled in non-dev contextMEDIUM

Finding: SEC-C-{NN}: CLAUDE.md contains {pattern} — {risk}

5.2 Settings Security

Check .claude/settings.json for:

CheckConditionSeverity
Allow-all permissionsPermissions set to * or allow_allHIGH
Disabled safety featuresAny safety/guard feature explicitly disabledCRITICAL
Unrestricted file accessNo file path restrictions configuredMEDIUM

Finding: SEC-C-{NN}: {description}

5.3 Production Config Leaks

Check for development/debug settings that should not be in production:

CheckFile(s)ConditionSeverity
Debug mode in prod configdocker-compose.yml, DockerfileNODE_ENV=development or DEBUG=*HIGH
Source maps in productionBuild configsourcemap: true in prod buildMEDIUM
Verbose loggingApp configLOG_LEVEL=debug in prodLOW
Dev dependencies in prodDockerfilenpm install without --production or --omit=devMEDIUM

Finding: SEC-C-{NN}: {description}


Grading System

After all phases complete, calculate a letter grade based on weighted findings.

Point Deductions

SeverityPoints per finding
CRITICAL-20
HIGH-10
MEDIUM-3
LOW-1
INFO0

Grade Thresholds

Start at 100 points, subtract per finding:

ScoreGradeAssessment
95-100AExcellent — minimal risk
85-94A-Strong — minor improvements possible
75-84BGood — some issues to address
65-74B-Acceptable — notable gaps
55-64CFair — significant issues
40-54C-Weak — multiple serious issues
25-39DPoor — immediate action needed
0-24FFailing — critical vulnerabilities present

Grade Caps

Regardless of total score, the grade is capped if:

ConditionMax grade
Any CRITICAL finding openD
3+ HIGH findings openC
No .gitignore for .envD
Secrets committed to gitF

Output Format

Security Scan: {project-name}
====================================

Grade: {letter} ({score}/100)

Phase 1: Secret Detection
  {OK | FINDINGS}
  - SEC-S-01 [CRITICAL] Hardcoded credential in src/config.ts:42
  - SEC-S-02 [HIGH] .env not in .gitignore

Phase 2: MCP Server Audit
  {OK | FINDINGS}
  - SEC-M-01 [HIGH] MCP server "custom-fs" has unrestricted file system access

Phase 3: Hook Safety
  {OK | FINDINGS}

Phase 4: Dependency Audit
  {OK | FINDINGS}
  - SEC-D-01 [CRITICAL] 2 critical vulnerabilities (npm audit)
  - SEC-D-02 [LOW] express is 2 major versions behind (4.x -> 5.x)

Phase 5: Configuration Review
  {OK | FINDINGS}
  - SEC-C-01 [HIGH] CLAUDE.md contains "skip security checks"

------------------------------------
Summary: {total} findings
  CRITICAL: {n}  HIGH: {n}  MEDIUM: {n}  LOW: {n}  INFO: {n}

{grade_explanation}

State File (.security-scan-state.json)

Written after every scan. Enables trend tracking across sessions.

{
  "version": "1.0",
  "scanDate": "2026-04-04",
  "project": "my-project",
  "grade": "B",
  "score": 78,
  "phases": {
    "secrets": { "status": "done", "findings": 2 },
    "mcp": { "status": "done", "findings": 1 },
    "hooks": { "status": "done", "findings": 0 },
    "deps": { "status": "done", "findings": 3 },
    "config": { "status": "done", "findings": 1 }
  },
  "findings": [
    {
      "id": "SEC-S-01",
      "phase": "secrets",
      "severity": "CRITICAL",
      "title": "Hardcoded credential in src/config.ts:42",
      "file": "src/config.ts",
      "line": 42,
      "status": "open"
    }
  ],
  "history": [
    { "date": "2026-03-20", "grade": "C", "score": 58, "findings": 12 },
    { "date": "2026-04-04", "grade": "B", "score": 78, "findings": 7 }
  ]
}

Smart Next Steps

After the scan completes, recommend follow-up actions based on findings:

ConditionRecommendation
CRITICAL secrets foundRemove secrets immediately, rotate affected credentials, add to .gitignore
MCP permission issuesReview .claude/settings.json, restrict server permissions to minimum needed
Hook safety concernsReview flagged hooks, replace dangerous patterns with safe alternatives
Dependency vulnerabilitiesRun npm audit fix, update outdated packages, review breaking changes
Config anti-patternsUpdate CLAUDE.md, remove debug settings from production configs
Grade D or FRun /security-scan again after fixes to verify improvement
Grade A or BRun /deploy-check to verify deployment readiness
Any findingsRun /adversarial-review code for deeper code-level security review
Auth detectedRun /auth-audit for authentication-specific security checks
AlwaysAdd security scan to CI pipeline (pre-commit or PR check)

Rules

  1. Read-only — Never modify project files, only analyze and report
  2. No false confidence — If a check cannot be performed (tool missing, file inaccessible), report as INFO, do not skip silently
  3. Cross-platform — Use node -e for JSON parsing, not jq. Avoid platform-specific commands
  4. Respect .gitignore — Do not scan node_modules/, .git/, dist/, build/, or other excluded directories
  5. No network calls — Do not send project data anywhere. All analysis is local
  6. Severity accuracy — Do not inflate or deflate severity. Follow the definitions exactly
  7. Idempotent — Running the scan twice produces the same result (unless project changed)
  8. Example detection — Do not flag obvious placeholder values (YOUR_KEY_HERE, changeme, xxx) as real secrets
  9. Privacy — Never log or display actual secret values. Show only pattern match and file location
  10. Anti-rationalization — Do not skip checks or reduce severity because the project "seems fine". See _shared/anti-rationalization.md

Files

security-scan/
├── SKILL.md      <- This file
└── skill.json    <- Skill metadata and triggers

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.