
Security Audit
- 17 installs
- 2.1k repo stars
- Updated June 18, 2026
- catlog22/claude-code-workflow
Support for security-audit
About
Provides workflow support for security-audit. Solo builders use this to streamline development.
- security-audit
Security Audit by the numbers
- 17 all-time installs (skills.sh)
- Ranked #2,075 of 3,282 Productivity & Planning skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/catlog22/claude-code-workflow --skill security-auditAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 17 |
|---|---|
| repo stars | ★ 2.1k |
| Last updated | June 18, 2026 |
| Repository | catlog22/claude-code-workflow ↗ |
What it does
Support for security-audit
Files
Security Audit
4-phase security audit covering supply chain risks, OWASP Top 10 code review, STRIDE threat modeling, and trend-tracked reporting. Produces structured JSON findings in .workflow/.security/.
Architecture Overview
+-------------------------------------------------------------------+
| Phase 1: Supply Chain Scan |
| -> Dependency audit, secrets detection, CI/CD review, LLM risks |
| -> Output: supply-chain-report.json |
+-----------------------------------+-------------------------------+
|
+-----------------------------------v-------------------------------+
| Phase 2: OWASP Review |
| -> OWASP Top 10 2021 code-level analysis via ccw cli |
| -> Output: owasp-findings.json |
+-----------------------------------+-------------------------------+
|
+-----------------------------------v-------------------------------+
| Phase 3: Threat Modeling (STRIDE) |
| -> 6 threat categories mapped to architecture components |
| -> Output: threat-model.json |
+-----------------------------------+-------------------------------+
|
+-----------------------------------v-------------------------------+
| Phase 4: Report & Tracking |
| -> Score calculation, trend comparison, dated report |
| -> Output: .workflow/.security/audit-report-{date}.json |
+-------------------------------------------------------------------+Key Design Principles
1. Infrastructure-first: Phase 1 catches low-hanging fruit (leaked secrets, vulnerable deps) before deeper analysis 2. Standards-based: OWASP Top 10 2021 and STRIDE provide systematic coverage 3. Scoring gates: Daily quick-scan must score 8/10; comprehensive audit minimum 2/10 for initial baseline 4. Trend tracking: Each audit compares against prior results in .workflow/.security/
Execution Flow
Quick-Scan Mode (daily)
Run Phase 1 only. Must score >= 8/10 to pass.
Comprehensive Mode (full audit)
Run all 4 phases sequentially. Initial baseline minimum 2/10.
Phase Sequence
1. Phase 1: Supply Chain Scan -- phases/01-supply-chain-scan.md
- Dependency audit (npm audit / pip-audit / safety check)
- Secrets detection (API keys, tokens, passwords in source)
- CI/CD config review (injection risks in workflow YAML)
- LLM/AI prompt injection check
2. Phase 2: OWASP Review -- phases/02-owasp-review.md
- Systematic OWASP Top 10 2021 code review
- Uses
ccw cli --tool gemini --mode analysis --rule analysis-assess-security-risks
3. Phase 3: Threat Modeling -- phases/03-threat-modeling.md
- STRIDE threat model mapped to architecture components
- Trust boundary identification and attack surface assessment
4. Phase 4: Report & Tracking -- phases/04-report-tracking.md
- Score calculation with severity weights
- Trend comparison with previous audits
- Date-stamped report to
.workflow/.security/
Scoring Overview
See specs/scoring-gates.md for full specification.
| Severity | Weight | Example |
|---|---|---|
| Critical | 10 | RCE, SQL injection, leaked credentials |
| High | 7 | Broken auth, SSRF, privilege escalation |
| Medium | 4 | XSS, CSRF, verbose error messages |
| Low | 1 | Missing headers, informational disclosures |
Gates: Daily quick-scan >= 8/10, Comprehensive initial >= 2/10.
Directory Setup
mkdir -p .workflow/.security
WORK_DIR=".workflow/.security"Output Structure
.workflow/.security/
audit-report-{YYYY-MM-DD}.json # Dated audit report
supply-chain-report.json # Latest supply chain scan
owasp-findings.json # Latest OWASP findings
threat-model.json # Latest STRIDE threat modelReference Documents
| Document | Purpose |
|---|---|
| phases/01-supply-chain-scan.md | Dependency, secrets, CI/CD, LLM risk scan |
| phases/02-owasp-review.md | OWASP Top 10 2021 code review |
| phases/03-threat-modeling.md | STRIDE threat modeling |
| phases/04-report-tracking.md | Report generation and trend tracking |
| specs/scoring-gates.md | Scoring system and quality gates |
| specs/owasp-checklist.md | OWASP Top 10 detection patterns |
Completion Status Protocol
This skill follows the Completion Status Protocol defined in _shared/SKILL-DESIGN-SPEC.md sections 13-14.
Possible termination statuses:
- DONE: All phases completed, score calculated, report generated
- DONE_WITH_CONCERNS: Audit completed but findings exceed acceptable thresholds
- BLOCKED: Required tools unavailable (e.g., npm/pip not installed), permission denied
- NEEDS_CONTEXT: Ambiguous project scope, unclear trust boundaries
Escalation follows the Three-Strike Rule (section 14) per step.
Phase 1: Supply Chain Scan
Detect low-hanging security risks in dependencies, secrets, CI/CD pipelines, and LLM/AI integrations.
Objective
- Audit third-party dependencies for known vulnerabilities
- Scan source code for leaked secrets and credentials
- Review CI/CD configuration for injection risks
- Check for LLM/AI prompt injection vulnerabilities
Execution Steps
Step 1: Dependency Audit
Detect package manager and run appropriate audit tool.
# Node.js projects
if [ -f package-lock.json ] || [ -f yarn.lock ]; then
npm audit --json > "${WORK_DIR}/npm-audit-raw.json" 2>&1 || true
fi
# Python projects
if [ -f requirements.txt ] || [ -f pyproject.toml ]; then
pip-audit --format json --output "${WORK_DIR}/pip-audit-raw.json" 2>&1 || true
# Fallback: safety check
safety check --json > "${WORK_DIR}/safety-raw.json" 2>&1 || true
fi
# Go projects
if [ -f go.sum ]; then
govulncheck ./... 2>&1 | tee "${WORK_DIR}/govulncheck-raw.txt" || true
fiIf audit tools are not installed, log as INFO finding and continue.
Step 2: Secrets Detection
Scan source files for hardcoded secrets using regex patterns.
# High-confidence patterns (case-insensitive)
grep -rniE \
'(api[_-]?key|api[_-]?secret|access[_-]?token|auth[_-]?token|secret[_-]?key)\s*[:=]\s*["\x27][A-Za-z0-9+/=_-]{16,}' \
--include='*.ts' --include='*.js' --include='*.py' --include='*.go' \
--include='*.java' --include='*.rb' --include='*.env' --include='*.yml' \
--include='*.yaml' --include='*.json' --include='*.toml' --include='*.cfg' \
. || true
# AWS patterns
grep -rniE '(AKIA[0-9A-Z]{16}|aws[_-]?secret[_-]?access[_-]?key)' . || true
# Private keys
grep -rniE '-----BEGIN (RSA |EC |DSA )?PRIVATE KEY-----' . || true
# Connection strings with passwords
grep -rniE '(mongodb|postgres|mysql|redis)://[^:]+:[^@]+@' . || true
# JWT tokens (hardcoded)
grep -rniE 'eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}' . || trueExclude: node_modules/, .git/, dist/, build/, __pycache__/, *.lock, *.min.js.
Step 3: CI/CD Config Review
Check GitHub Actions and other CI/CD configs for injection risks.
# Find workflow files
find .github/workflows -name '*.yml' -o -name '*.yaml' 2>/dev/null
# Check for expression injection in run: blocks
# Dangerous: ${{ github.event.pull_request.title }} in run:
grep -rn '\${{.*github\.event\.' .github/workflows/ 2>/dev/null || true
# Check for pull_request_target with checkout of PR code
grep -rn 'pull_request_target' .github/workflows/ 2>/dev/null || true
# Check for use of deprecated/vulnerable actions
grep -rn 'actions/checkout@v1\|actions/checkout@v2' .github/workflows/ 2>/dev/null || true
# Check for secrets passed to untrusted contexts
grep -rn 'secrets\.' .github/workflows/ 2>/dev/null || trueStep 4: LLM/AI Prompt Injection Check
Scan for patterns indicating prompt injection risk in LLM integrations.
# User input concatenated directly into prompts
grep -rniE '(prompt|system_message|messages)\s*[+=].*\b(user_input|request\.(body|query|params)|req\.)' \
--include='*.ts' --include='*.js' --include='*.py' . || true
# Template strings with user data in LLM calls
grep -rniE '(openai|anthropic|llm|chat|completion)\.' \
--include='*.ts' --include='*.js' --include='*.py' . || true
# Check for missing input sanitization before LLM calls
grep -rniE 'f".*{.*}.*".*\.(chat|complete|generate)' \
--include='*.py' . || trueOutput
- File:
supply-chain-report.json - Location:
${WORK_DIR}/supply-chain-report.json - Format: JSON
{
"phase": "supply-chain-scan",
"timestamp": "ISO-8601",
"findings": [
{
"category": "dependency|secret|cicd|llm",
"severity": "critical|high|medium|low",
"title": "Finding title",
"description": "Detailed description",
"file": "path/to/file",
"line": 42,
"evidence": "matched text or context",
"remediation": "How to fix"
}
],
"summary": {
"total": 0,
"by_severity": { "critical": 0, "high": 0, "medium": 0, "low": 0 },
"by_category": { "dependency": 0, "secret": 0, "cicd": 0, "llm": 0 }
}
}Next Phase
Proceed to Phase 2: OWASP Review with supply chain findings as context.
Phase 2: OWASP Review
Systematic code-level review against OWASP Top 10 2021 categories.
Objective
- Review codebase against all 10 OWASP Top 10 2021 categories
- Use CCW CLI multi-model analysis for comprehensive coverage
- Produce structured findings with file:line references and remediation steps
Prerequisites
- Phase 1 supply-chain-report.json (provides dependency context)
- Read specs/owasp-checklist.md for detection patterns
Execution Steps
Step 1: Identify Target Scope
# Identify source directories (exclude deps, build, test fixtures)
# Focus on: API routes, auth modules, data access, input handlers
find . -type f \( -name '*.ts' -o -name '*.js' -o -name '*.py' -o -name '*.go' -o -name '*.java' \) \
! -path '*/node_modules/*' ! -path '*/dist/*' ! -path '*/.git/*' \
! -path '*/build/*' ! -path '*/__pycache__/*' ! -path '*/vendor/*' \
| head -200Step 2: CCW CLI Analysis
Run multi-model security analysis using the security risks rule template.
ccw cli -p "PURPOSE: OWASP Top 10 2021 security audit of this codebase.
Systematically check each OWASP category:
A01 Broken Access Control | A02 Cryptographic Failures | A03 Injection |
A04 Insecure Design | A05 Security Misconfiguration | A06 Vulnerable Components |
A07 Identification/Auth Failures | A08 Software/Data Integrity Failures |
A09 Security Logging/Monitoring Failures | A10 SSRF
TASK: For each OWASP category, scan relevant code patterns, identify vulnerabilities with file:line references, classify severity, provide remediation.
MODE: analysis
CONTEXT: @src/**/* @**/*.config.* @**/*.env.example
EXPECTED: JSON-structured findings per OWASP category with severity, file:line, evidence, remediation.
CONSTRAINTS: Code-level analysis only | Every finding must have file:line reference | Focus on real vulnerabilities not theoretical risks
" --tool gemini --mode analysis --rule analysis-assess-security-risksStep 3: Manual Pattern Scanning
Supplement CLI analysis with targeted pattern scans per OWASP category. Reference specs/owasp-checklist.md for full pattern list.
A01 - Broken Access Control:
# Missing auth middleware on routes
grep -rn 'app\.\(get\|post\|put\|delete\|patch\)(' --include='*.ts' --include='*.js' . | grep -v 'auth\|middleware\|protect'
# Direct object references without ownership check
grep -rn 'params\.id\|req\.params\.' --include='*.ts' --include='*.js' . || trueA03 - Injection:
# SQL string concatenation
grep -rniE '(query|execute|raw)\s*\(\s*[`"'\'']\s*SELECT.*\+\s*|f".*SELECT.*{' --include='*.ts' --include='*.js' --include='*.py' . || true
# Command injection
grep -rniE '(exec|spawn|system|popen|subprocess)\s*\(' --include='*.ts' --include='*.js' --include='*.py' . || trueA05 - Security Misconfiguration:
# Debug mode enabled
grep -rniE '(DEBUG|debug)\s*[:=]\s*(true|True|1|"true")' --include='*.env' --include='*.py' --include='*.ts' --include='*.json' . || true
# CORS wildcard
grep -rniE "cors.*\*|Access-Control-Allow-Origin.*\*" --include='*.ts' --include='*.js' --include='*.py' . || trueA07 - Identification and Authentication Failures:
# Weak password patterns
grep -rniE 'password.*length.*[0-5][^0-9]|minlength.*[0-5][^0-9]' --include='*.ts' --include='*.js' --include='*.py' . || true
# Hardcoded credentials
grep -rniE '(password|passwd|pwd)\s*[:=]\s*["\x27][^"\x27]{3,}' --include='*.ts' --include='*.js' --include='*.py' --include='*.env' . || trueStep 4: Consolidate Findings
Merge CLI analysis results and manual pattern scan results. Deduplicate and classify by OWASP category.
OWASP Top 10 2021 Categories
| ID | Category | Key Checks |
|---|---|---|
| A01 | Broken Access Control | Missing auth, IDOR, path traversal, CORS |
| A02 | Cryptographic Failures | Weak algorithms, plaintext storage, missing TLS |
| A03 | Injection | SQL, NoSQL, OS command, LDAP, XPath injection |
| A04 | Insecure Design | Missing threat modeling, insecure business logic |
| A05 | Security Misconfiguration | Debug enabled, default creds, verbose errors |
| A06 | Vulnerable and Outdated Components | Known CVEs in dependencies (from Phase 1) |
| A07 | Identification and Authentication Failures | Weak passwords, missing MFA, session issues |
| A08 | Software and Data Integrity Failures | Unsigned updates, insecure deserialization, CI/CD |
| A09 | Security Logging and Monitoring Failures | Missing audit logs, no alerting, insufficient logging |
| A10 | Server-Side Request Forgery (SSRF) | Unvalidated URLs, internal resource access |
Output
- File:
owasp-findings.json - Location:
${WORK_DIR}/owasp-findings.json - Format: JSON
{
"phase": "owasp-review",
"timestamp": "ISO-8601",
"owasp_version": "2021",
"findings": [
{
"owasp_id": "A01",
"owasp_category": "Broken Access Control",
"severity": "critical|high|medium|low",
"title": "Finding title",
"description": "Detailed description",
"file": "path/to/file",
"line": 42,
"evidence": "code snippet or pattern match",
"remediation": "Specific fix recommendation",
"cwe": "CWE-XXX"
}
],
"coverage": {
"A01": "checked|not_applicable",
"A02": "checked|not_applicable",
"A03": "checked|not_applicable",
"A04": "checked|not_applicable",
"A05": "checked|not_applicable",
"A06": "checked|not_applicable",
"A07": "checked|not_applicable",
"A08": "checked|not_applicable",
"A09": "checked|not_applicable",
"A10": "checked|not_applicable"
},
"summary": {
"total": 0,
"by_severity": { "critical": 0, "high": 0, "medium": 0, "low": 0 },
"categories_checked": 10,
"categories_with_findings": 0
}
}Next Phase
Proceed to Phase 3: Threat Modeling with OWASP findings as input for STRIDE analysis.
Phase 3: Threat Modeling (STRIDE)
Map STRIDE threat categories to architecture components, identify trust boundaries, and assess attack surface.
Objective
- Apply the STRIDE threat model to the project architecture
- Identify trust boundaries between system components
- Assess attack surface area per component
- Cross-reference with Phase 1 and Phase 2 findings
STRIDE Categories
| Category | Threat | Question | Typical Targets |
|---|---|---|---|
| S - Spoofing | Identity impersonation | Can an attacker pretend to be someone else? | Auth endpoints, API keys, session tokens |
| T - Tampering | Data modification | Can data be modified in transit or at rest? | Request bodies, database records, config files |
| R - Repudiation | Deniable actions | Can a user deny performing an action? | Audit logs, transaction records, user actions |
| I - Information Disclosure | Data leakage | Can sensitive data be exposed? | Error messages, logs, API responses, storage |
| D - Denial of Service | Availability disruption | Can the system be made unavailable? | API endpoints, resource-intensive operations |
| E - Elevation of Privilege | Unauthorized access | Can a user gain higher privileges? | Role checks, admin routes, permission logic |
Execution Steps
Step 1: Architecture Component Discovery
Identify major system components by scanning project structure.
# Identify entry points (API routes, CLI commands, event handlers)
grep -rlE '(app\.(get|post|put|delete|patch|use)|router\.|@app\.route|@router\.)' \
--include='*.ts' --include='*.js' --include='*.py' . || true
# Identify data stores (database connections, file storage)
grep -rlE '(createConnection|mongoose\.connect|sqlite|redis|S3|createClient)' \
--include='*.ts' --include='*.js' --include='*.py' . || true
# Identify external service integrations
grep -rlE '(fetch|axios|http\.request|requests\.(get|post)|urllib)' \
--include='*.ts' --include='*.js' --include='*.py' . || true
# Identify auth/session components
grep -rlE '(jwt|passport|session|oauth|bcrypt|argon2|crypto)' \
--include='*.ts' --include='*.js' --include='*.py' . || trueStep 2: Trust Boundary Identification
Map trust boundaries in the system:
1. External boundary: User/browser <-> Application server 2. Service boundary: Application <-> External APIs/services 3. Data boundary: Application <-> Database/storage 4. Internal boundary: Public routes <-> Authenticated routes <-> Admin routes 5. Process boundary: Main process <-> Worker/subprocess
For each boundary, document:
- What crosses the boundary (data types, credentials)
- How the boundary is enforced (middleware, TLS, auth)
- What happens when enforcement fails
Step 3: STRIDE per Component
For each discovered component, systematically evaluate all 6 STRIDE categories:
Spoofing Analysis:
- Are authentication mechanisms in place at all entry points?
- Can API keys or tokens be forged or replayed?
- Are session tokens properly validated and rotated?
Tampering Analysis:
- Is input validation applied before processing?
- Are database queries parameterized?
- Can request bodies or headers be manipulated to alter behavior?
- Are file uploads validated for type and content?
Repudiation Analysis:
- Are user actions logged with sufficient detail (who, what, when)?
- Are logs tamper-proof or centralized?
- Can critical operations (payments, deletions) be traced to a user?
Information Disclosure Analysis:
- Do error responses leak stack traces or internal paths?
- Are sensitive fields (passwords, tokens) excluded from logs and API responses?
- Is PII properly handled (encryption at rest, masking in logs)?
- Do debug endpoints or verbose modes expose internals?
Denial of Service Analysis:
- Are rate limits applied to public endpoints?
- Can resource-intensive operations be triggered without limits?
- Are file upload sizes bounded?
- Are database queries bounded (pagination, timeouts)?
Elevation of Privilege Analysis:
- Are role/permission checks applied consistently?
- Can horizontal privilege escalation occur (accessing other users' data)?
- Can vertical escalation occur (user -> admin)?
- Are admin/debug routes properly protected?
Step 4: Attack Surface Assessment
Quantify the attack surface:
Attack Surface = Sum of:
- Number of public API endpoints
- Number of external service integrations
- Number of user-controllable input points
- Number of privileged operations
- Number of data stores with sensitive contentRate each component:
- High exposure: Public-facing, handles sensitive data, complex logic
- Medium exposure: Authenticated access, moderate data sensitivity
- Low exposure: Internal only, no sensitive data, simple operations
Output
- File:
threat-model.json - Location:
${WORK_DIR}/threat-model.json - Format: JSON
{
"phase": "threat-modeling",
"timestamp": "ISO-8601",
"framework": "STRIDE",
"components": [
{
"name": "Component name",
"type": "api_endpoint|data_store|external_service|auth_module|worker",
"files": ["path/to/file.ts"],
"exposure": "high|medium|low",
"trust_boundaries": ["external", "data"],
"threats": {
"spoofing": {
"applicable": true,
"findings": ["Description of threat"],
"mitigations": ["Existing mitigation"],
"gaps": ["Missing mitigation"]
},
"tampering": { "applicable": true, "findings": [], "mitigations": [], "gaps": [] },
"repudiation": { "applicable": true, "findings": [], "mitigations": [], "gaps": [] },
"information_disclosure": { "applicable": true, "findings": [], "mitigations": [], "gaps": [] },
"denial_of_service": { "applicable": true, "findings": [], "mitigations": [], "gaps": [] },
"elevation_of_privilege": { "applicable": true, "findings": [], "mitigations": [], "gaps": [] }
}
}
],
"trust_boundaries": [
{
"name": "Boundary name",
"from": "Component A",
"to": "Component B",
"enforcement": "TLS|auth_middleware|API_key",
"data_crossing": ["request bodies", "credentials"],
"risk_level": "high|medium|low"
}
],
"attack_surface": {
"public_endpoints": 0,
"external_integrations": 0,
"input_points": 0,
"privileged_operations": 0,
"sensitive_data_stores": 0,
"total_score": 0
},
"summary": {
"components_analyzed": 0,
"threats_identified": 0,
"by_stride": { "S": 0, "T": 0, "R": 0, "I": 0, "D": 0, "E": 0 },
"high_exposure_components": 0
}
}Next Phase
Proceed to Phase 4: Report & Tracking with the threat model to generate the final scored audit report.
Phase 4: Report & Tracking
Generate scored audit report, compare with previous audits, and track trends.
Objective
- Calculate security score from all phase findings
- Compare with previous audit results (if available)
- Generate date-stamped report in
.workflow/.security/ - Track improvement or regression trends
Prerequisites
- Phase 1:
supply-chain-report.json - Phase 2:
owasp-findings.json - Phase 3:
threat-model.json - Previous audit:
.workflow/.security/audit-report-*.json(optional)
Execution Steps
Step 1: Aggregate Findings
Collect all findings from phases 1-3 and classify by severity.
All findings =
supply-chain-report.findings
+ owasp-findings.findings
+ threat-model threats (where gaps exist)Step 2: Calculate Score
Apply scoring formula from specs/scoring-gates.md:
Base score = 10.0
For each finding:
penalty = severity_weight / total_files_scanned
- Critical: weight = 10 (each critical finding has outsized impact)
- High: weight = 7
- Medium: weight = 4
- Low: weight = 1
Weighted penalty = SUM(finding_weight * count_per_severity) / normalization_factor
Final score = max(0, 10.0 - weighted_penalty)
Normalization factor = max(10, total_files_scanned)Score interpretation:
| Score | Rating | Meaning |
|---|---|---|
| 9-10 | Excellent | Minimal risk, production-ready |
| 7-8 | Good | Acceptable risk, minor improvements needed |
| 5-6 | Fair | Notable risks, remediation recommended |
| 3-4 | Poor | Significant risks, remediation required |
| 0-2 | Critical | Severe vulnerabilities, immediate action needed |
Step 3: Gate Evaluation
Daily quick-scan gate (Phase 1 only):
- PASS: score >= 8/10
- FAIL: score < 8/10 -- block deployment or flag for review
Comprehensive audit gate (all phases):
- For initial/baseline: PASS if score >= 2/10 (establishes baseline)
- For subsequent: PASS if score >= previous_score (no regression)
- Target: score >= 7/10 for production readiness
Step 4: Trend Comparison
# Find previous audit reports
ls -t .workflow/.security/audit-report-*.json 2>/dev/null | head -5Compare current vs. previous:
- Delta per OWASP category
- Delta per STRIDE category
- New findings vs. resolved findings
- Overall score trend
Step 5: Generate Report
Write the final report with all consolidated data.
Output
- File:
audit-report-{YYYY-MM-DD}.json - Location:
.workflow/.security/audit-report-{YYYY-MM-DD}.json - Format: JSON
{
"report": "security-audit",
"version": "1.0",
"timestamp": "ISO-8601",
"date": "YYYY-MM-DD",
"mode": "comprehensive|quick-scan",
"score": {
"overall": 7.5,
"rating": "Good",
"gate": "PASS|FAIL",
"gate_threshold": 8
},
"findings_summary": {
"total": 0,
"by_severity": { "critical": 0, "high": 0, "medium": 0, "low": 0 },
"by_phase": {
"supply_chain": 0,
"owasp": 0,
"stride": 0
},
"by_owasp": {
"A01": 0, "A02": 0, "A03": 0, "A04": 0, "A05": 0,
"A06": 0, "A07": 0, "A08": 0, "A09": 0, "A10": 0
},
"by_stride": { "S": 0, "T": 0, "R": 0, "I": 0, "D": 0, "E": 0 }
},
"top_risks": [
{
"rank": 1,
"title": "Most critical finding",
"severity": "critical",
"source_phase": "owasp",
"remediation": "How to fix",
"effort": "low|medium|high"
}
],
"trend": {
"previous_date": "YYYY-MM-DD or null",
"previous_score": 0,
"score_delta": 0,
"new_findings": 0,
"resolved_findings": 0,
"direction": "improving|stable|regressing|baseline"
},
"phases_completed": ["supply-chain-scan", "owasp-review", "threat-modeling", "report-tracking"],
"files_scanned": 0,
"remediation_priority": [
{
"priority": 1,
"finding": "Finding title",
"effort": "low",
"impact": "high",
"recommendation": "Specific action"
}
]
}Report Storage
# Ensure directory exists
mkdir -p .workflow/.security
# Write report with date stamp
DATE=$(date +%Y-%m-%d)
cp "${WORK_DIR}/audit-report.json" ".workflow/.security/audit-report-${DATE}.json"
# Also maintain latest copies of phase outputs
cp "${WORK_DIR}/supply-chain-report.json" ".workflow/.security/" 2>/dev/null || true
cp "${WORK_DIR}/owasp-findings.json" ".workflow/.security/" 2>/dev/null || true
cp "${WORK_DIR}/threat-model.json" ".workflow/.security/" 2>/dev/null || trueCompletion
After report generation, output skill completion status per the Completion Status Protocol:
- DONE: All phases completed, report generated, score calculated
- DONE_WITH_CONCERNS: Report generated but score below target or regression detected
- BLOCKED: Phase data missing or corrupted
OWASP Top 10 2021 Checklist
Code-level detection patterns, vulnerable code examples, and remediation templates for each OWASP category.
When to Use
| Phase | Usage | Section |
|---|---|---|
| Phase 2 | Reference during OWASP code review | All categories |
| Phase 4 | Classify findings by OWASP category | Category IDs |
---
A01: Broken Access Control
CWE: CWE-200, CWE-284, CWE-285, CWE-352, CWE-639
Detection Patterns
# Missing auth middleware on route handlers
grep -rnE 'app\.(get|post|put|delete|patch)\s*\(\s*["\x27/]' --include='*.ts' --include='*.js' .
# Then verify each route has auth middleware
# Direct object reference without ownership check
grep -rnE 'findById\(.*params|findOne\(.*params|\.get\(.*id' --include='*.ts' --include='*.js' --include='*.py' .
# Path traversal patterns
grep -rnE '(readFile|writeFile|createReadStream|open)\s*\(.*req\.' --include='*.ts' --include='*.js' .
grep -rnE 'os\.path\.join\(.*request\.' --include='*.py' .
# Missing CORS restrictions
grep -rnE 'Access-Control-Allow-Origin.*\*|cors\(\s*\)' --include='*.ts' --include='*.js' .Vulnerable Code Example
// BAD: No ownership check
app.get('/api/documents/:id', auth, async (req, res) => {
const doc = await Document.findById(req.params.id); // Any user can access any doc
res.json(doc);
});Remediation
// GOOD: Ownership check
app.get('/api/documents/:id', auth, async (req, res) => {
const doc = await Document.findOne({ _id: req.params.id, owner: req.user.id });
if (!doc) return res.status(404).json({ error: 'Not found' });
res.json(doc);
});---
A02: Cryptographic Failures
CWE: CWE-259, CWE-327, CWE-331, CWE-798
Detection Patterns
# Weak hash algorithms
grep -rniE '(md5|sha1)\s*\(' --include='*.ts' --include='*.js' --include='*.py' --include='*.java' .
# Plaintext password storage
grep -rniE 'password\s*[:=]\s*.*\.(body|query|params)' --include='*.ts' --include='*.js' .
# Hardcoded encryption keys
grep -rniE '(encrypt|cipher|secret|key)\s*[:=]\s*["\x27][A-Za-z0-9+/=]{8,}' --include='*.ts' --include='*.js' --include='*.py' .
# HTTP (not HTTPS) for sensitive operations
grep -rniE 'http://.*\.(api|auth|login|payment)' --include='*.ts' --include='*.js' --include='*.py' .
# Missing encryption at rest
grep -rniE '(password|ssn|credit.?card|social.?security)' --include='*.sql' --include='*.prisma' --include='*.schema' .Vulnerable Code Example
# BAD: MD5 for password hashing
import hashlib
password_hash = hashlib.md5(password.encode()).hexdigest()Remediation
# GOOD: bcrypt with proper work factor
import bcrypt
password_hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))---
A03: Injection
CWE: CWE-20, CWE-74, CWE-79, CWE-89
Detection Patterns
# SQL string concatenation/interpolation
grep -rniE "(query|execute|raw)\s*\(\s*[\`\"'].*(\+|\$\{|%s|\.format)" --include='*.ts' --include='*.js' --include='*.py' .
grep -rniE "f[\"'].*SELECT.*\{" --include='*.py' .
# NoSQL injection
grep -rniE '\$where|\$regex.*req\.' --include='*.ts' --include='*.js' .
grep -rniE 'find\(\s*\{.*req\.(body|query|params)' --include='*.ts' --include='*.js' .
# OS command injection
grep -rniE '(child_process|exec|execSync|spawn|system|popen|subprocess)\s*\(.*req\.' --include='*.ts' --include='*.js' --include='*.py' .
# XPath/LDAP injection
grep -rniE '(xpath|ldap).*\+.*req\.' --include='*.ts' --include='*.js' --include='*.py' .
# Template injection
grep -rniE '(render_template_string|Template\(.*req\.|eval\(.*req\.)' --include='*.py' --include='*.js' .Vulnerable Code Example
// BAD: SQL string concatenation
const result = await db.query(`SELECT * FROM users WHERE id = ${req.params.id}`);Remediation
// GOOD: Parameterized query
const result = await db.query('SELECT * FROM users WHERE id = $1', [req.params.id]);---
A04: Insecure Design
CWE: CWE-209, CWE-256, CWE-501, CWE-522
Detection Patterns
# Missing rate limiting on auth endpoints
grep -rniE '(login|register|reset.?password|forgot.?password)' --include='*.ts' --include='*.js' --include='*.py' .
# Then check if rate limiting middleware is applied
# No account lockout mechanism
grep -rniE 'failed.?login|login.?attempt|max.?retries' --include='*.ts' --include='*.js' --include='*.py' .
# Business logic without validation
grep -rniE '(transfer|withdraw|purchase|delete.?account)' --include='*.ts' --include='*.js' --include='*.py' .
# Then check for confirmation/validation stepsChecks
- [ ] Authentication flows have rate limiting
- [ ] Account lockout after N failed attempts
- [ ] Multi-step operations have proper state validation
- [ ] Business-critical operations require confirmation
- [ ] Threat modeling has been performed (see Phase 3)
Remediation
Implement defense-in-depth: rate limiting, input validation, business logic validation, and multi-step confirmation for critical operations.
---
A05: Security Misconfiguration
CWE: CWE-2, CWE-11, CWE-13, CWE-15, CWE-16, CWE-388
Detection Patterns
# Debug mode enabled
grep -rniE '(DEBUG|NODE_ENV)\s*[:=]\s*(true|True|1|"development"|"debug")' \
--include='*.env' --include='*.env.*' --include='*.py' --include='*.json' --include='*.yaml' .
# Default credentials
grep -rniE '(admin|root|test|default).*[:=].*password' --include='*.env' --include='*.yaml' --include='*.json' --include='*.py' .
# Verbose error responses (stack traces to client)
grep -rniE '(stack|stackTrace|traceback).*res\.(json|send)|app\.use.*err.*stack' --include='*.ts' --include='*.js' .
# Missing security headers
grep -rniE '(helmet|X-Frame-Options|X-Content-Type-Options|Strict-Transport-Security)' --include='*.ts' --include='*.js' .
# Directory listing enabled
grep -rniE 'autoindex\s+on|directory.?listing|serveStatic.*index.*false' --include='*.conf' --include='*.ts' --include='*.js' .
# Unnecessary features/services
grep -rniE '(graphiql|playground|swagger-ui).*true' --include='*.ts' --include='*.js' --include='*.py' --include='*.yaml' .Vulnerable Code Example
// BAD: Stack trace in error response
app.use((err, req, res, next) => {
res.status(500).json({ error: err.message, stack: err.stack });
});Remediation
// GOOD: Generic error response in production
app.use((err, req, res, next) => {
console.error(err.stack); // Log internally
res.status(500).json({ error: 'Internal server error' });
});---
A06: Vulnerable and Outdated Components
CWE: CWE-1104
Detection Patterns
# Check dependency lock files age
ls -la package-lock.json yarn.lock requirements.txt Pipfile.lock go.sum 2>/dev/null
# Run package audits (from Phase 1)
npm audit --json 2>/dev/null
pip-audit --format json 2>/dev/null
# Check for pinned vs unpinned dependencies
grep -E ':\s*"\^|:\s*"~|:\s*"\*|>=\s' package.json 2>/dev/null
grep -E '^[a-zA-Z].*[^=]==[^=]' requirements.txt 2>/dev/null # Good: pinned
grep -E '^[a-zA-Z].*>=|^[a-zA-Z][^=]*$' requirements.txt 2>/dev/null # Bad: unpinnedChecks
- [ ] All dependencies have pinned versions
- [ ] No known CVEs in dependencies (via audit tools)
- [ ] Dependencies are actively maintained (not abandoned)
- [ ] Lock files are committed to version control
Remediation
Run npm audit fix or pip install --upgrade for vulnerable packages. Pin all dependency versions. Set up automated dependency scanning (Dependabot, Renovate).
---
A07: Identification and Authentication Failures
CWE: CWE-255, CWE-259, CWE-287, CWE-384
Detection Patterns
# Weak password requirements
grep -rniE 'password.*length.*[0-5]|minlength.*[0-5]|min.?length.*[0-5]' --include='*.ts' --include='*.js' --include='*.py' .
# Missing password hashing
grep -rniE 'password\s*[:=].*req\.' --include='*.ts' --include='*.js' .
# Then check if bcrypt/argon2/scrypt is used before storage
# Session fixation (no rotation after login)
grep -rniE 'session\.regenerate|session\.id\s*=' --include='*.ts' --include='*.js' .
# JWT without expiration
grep -rniE 'jwt\.sign\(' --include='*.ts' --include='*.js' .
# Then check for expiresIn option
# Credentials in URL
grep -rniE '(token|key|password|secret)=[^&\s]+' --include='*.ts' --include='*.js' --include='*.py' .Vulnerable Code Example
// BAD: JWT without expiration
const token = jwt.sign({ userId: user.id }, SECRET);Remediation
// GOOD: JWT with expiration and proper claims
const token = jwt.sign(
{ userId: user.id, role: user.role },
SECRET,
{ expiresIn: '1h', issuer: 'myapp', audience: 'myapp-client' }
);---
A08: Software and Data Integrity Failures
CWE: CWE-345, CWE-353, CWE-426, CWE-494, CWE-502
Detection Patterns
# Insecure deserialization
grep -rniE '(pickle\.load|yaml\.load\(|unserialize|JSON\.parse\(.*req\.|eval\()' --include='*.py' --include='*.ts' --include='*.js' --include='*.php' .
# Missing integrity checks on downloads/updates
grep -rniE '(download|fetch|curl|wget)' --include='*.sh' --include='*.yaml' --include='*.yml' .
# Then check for checksum/signature verification
# CI/CD pipeline without pinned action versions
grep -rniE 'uses:\s*[^@]+$|uses:.*@(main|master|latest)' .github/workflows/*.yml 2>/dev/null
# Unsafe YAML loading
grep -rniE 'yaml\.load\(' --include='*.py' .
# Should be yaml.safe_load()Vulnerable Code Example
# BAD: Unsafe YAML loading
import yaml
data = yaml.load(user_input) # Allows arbitrary code executionRemediation
# GOOD: Safe YAML loading
import yaml
data = yaml.safe_load(user_input)---
A09: Security Logging and Monitoring Failures
CWE: CWE-223, CWE-532, CWE-778
Detection Patterns
# Check for logging of auth events
grep -rniE '(log|logger|logging)\.' --include='*.ts' --include='*.js' --include='*.py' .
# Then check if login/logout/failed-auth events are logged
# Sensitive data in logs
grep -rniE 'log.*(password|token|secret|credit.?card|ssn)' --include='*.ts' --include='*.js' --include='*.py' .
# Empty catch blocks (swallowed errors)
grep -rniE 'catch\s*\([^)]*\)\s*\{\s*\}' --include='*.ts' --include='*.js' .
# Missing audit trail for critical operations
grep -rniE '(delete|update|create|transfer)' --include='*.ts' --include='*.js' --include='*.py' .
# Then check if these operations are logged with user contextChecks
- [ ] Failed login attempts are logged with IP and timestamp
- [ ] Successful logins are logged
- [ ] Access control failures are logged
- [ ] Input validation failures are logged
- [ ] Sensitive data is NOT logged (passwords, tokens, PII)
- [ ] Logs include sufficient context (who, what, when, where)
Remediation
Implement structured logging with: user ID, action, timestamp, IP address, result (success/failure). Exclude sensitive data. Set up log monitoring and alerting for anomalous patterns.
---
A10: Server-Side Request Forgery (SSRF)
CWE: CWE-918
Detection Patterns
# User-controlled URLs in fetch/request calls
grep -rniE '(fetch|axios|http\.request|requests\.(get|post)|urllib)\s*\(.*req\.(body|query|params)' \
--include='*.ts' --include='*.js' --include='*.py' .
# URL construction from user input
grep -rniE '(url|endpoint|target|redirect)\s*[:=].*req\.(body|query|params)' --include='*.ts' --include='*.js' --include='*.py' .
# Image/file fetch from URL
grep -rniE '(download|fetchImage|getFile|loadUrl)\s*\(.*req\.' --include='*.ts' --include='*.js' --include='*.py' .
# Redirect without validation
grep -rniE 'res\.redirect\(.*req\.|redirect_to.*request\.' --include='*.ts' --include='*.js' --include='*.py' .Vulnerable Code Example
// BAD: Unvalidated URL fetch
app.get('/proxy', async (req, res) => {
const response = await fetch(req.query.url); // Can access internal services
res.send(await response.text());
});Remediation
// GOOD: URL allowlist validation
const ALLOWED_HOSTS = ['api.example.com', 'cdn.example.com'];
app.get('/proxy', async (req, res) => {
const url = new URL(req.query.url);
if (!ALLOWED_HOSTS.includes(url.hostname)) {
return res.status(400).json({ error: 'Host not allowed' });
}
if (url.protocol !== 'https:') {
return res.status(400).json({ error: 'HTTPS required' });
}
const response = await fetch(url.toString());
res.send(await response.text());
});---
Quick Reference
| ID | Category | Key Grep Pattern | Severity Baseline |
|---|---|---|---|
| A01 | Broken Access Control | findById.*params without owner check | High |
| A02 | Cryptographic Failures | `md5\ | sha1` for passwords |
| A03 | Injection | `query.\+.req\.\ | f".SELECT.\{` |
| A04 | Insecure Design | Missing rate limit on auth routes | Medium |
| A05 | Security Misconfiguration | `DEBUG.*true\ | stack.*res.json` |
| A06 | Vulnerable Components | npm audit / pip-audit results | Varies |
| A07 | Auth Failures | jwt.sign without expiresIn | High |
| A08 | Integrity Failures | `pickle.load\ | yaml.load` |
| A09 | Logging Failures | Empty catch blocks, no auth logging | Medium |
| A10 | SSRF | fetch.*req.query.url | High |
Scoring Gates
Defines the 10-point scoring system, severity weights, quality gates, and trend tracking format for security audits.
When to Use
| Phase | Usage | Section |
|---|---|---|
| Phase 1 | Quick-scan scoring (daily gate) | Severity Weights, Daily Gate |
| Phase 4 | Full audit scoring and reporting | All sections |
---
10-Point Scale
All security audit scores are on a 0-10 scale where 10 = no findings and 0 = critical exposure.
| Score | Rating | Description |
|---|---|---|
| 9.0 - 10.0 | Excellent | Minimal risk. Production-ready without reservations. |
| 7.0 - 8.9 | Good | Low risk. Acceptable for production with minor improvements. |
| 5.0 - 6.9 | Fair | Moderate risk. Remediation recommended before production. |
| 3.0 - 4.9 | Poor | High risk. Remediation required. Not production-ready. |
| 0.0 - 2.9 | Critical | Severe exposure. Immediate action required. |
Severity Weights
Each finding is weighted by severity for score calculation.
| Severity | Weight | Criteria | Examples |
|---|---|---|---|
| Critical | 10 | Exploitable with high impact, no user interaction needed | RCE, SQL injection with data access, leaked production credentials, auth bypass |
| High | 7 | Exploitable with significant impact, may need user interaction | Broken authentication, SSRF, privilege escalation, XSS with session theft |
| Medium | 4 | Limited exploitability or moderate impact | Reflected XSS, CSRF, verbose error messages, missing security headers |
| Low | 1 | Informational or minimal impact | Missing best-practice headers, minor info disclosure, deprecated dependencies without known exploit |
Score Calculation
Input:
findings[] -- array of all findings with severity
files_scanned -- total source files analyzed
Algorithm:
base_score = 10.0
normalization = max(10, files_scanned)
weighted_sum = 0
for each finding:
weighted_sum += severity_weight(finding.severity)
penalty = weighted_sum / normalization
final_score = max(0, base_score - penalty)
final_score = round(final_score, 1)
return final_scoreExample:
| Findings | Files Scanned | Weighted Sum | Penalty | Score |
|---|---|---|---|---|
| 1 critical | 50 | 10 | 0.2 | 9.8 |
| 2 critical, 3 high | 50 | 41 | 0.82 | 9.2 |
| 5 critical, 10 high | 50 | 120 | 2.4 | 7.6 |
| 10 critical, 20 high, 15 medium | 100 | 300 | 3.0 | 7.0 |
| 20 critical | 20 | 200 | 10.0 | 0.0 |
Quality Gates
Daily Quick-Scan Gate
Applies to Phase 1 (Supply Chain Scan) only.
| Result | Condition | Action |
|---|---|---|
| PASS | score >= 8.0 | Continue. No blocking issues. |
| WARN | 6.0 <= score < 8.0 | Log warning. Review findings before deploy. |
| FAIL | score < 6.0 | Block deployment. Remediate critical/high findings. |
Comprehensive Audit Gate
Applies to full audit (all 4 phases).
Initial/Baseline audit (no previous audit exists):
| Result | Condition | Action |
|---|---|---|
| PASS | score >= 2.0 | Baseline established. Plan remediation. |
| FAIL | score < 2.0 | Critical exposure. Immediate triage required. |
Subsequent audits (previous audit exists):
| Result | Condition | Action |
|---|---|---|
| PASS | score >= previous_score | No regression. Continue improvement. |
| WARN | score within 0.5 of previous | Marginal change. Review new findings. |
| FAIL | score < previous_score - 0.5 | Regression detected. Investigate new findings. |
Production readiness target: score >= 7.0
Trend Tracking Format
Each audit report stores trend data for comparison.
{
"trend": {
"current_date": "2026-03-29",
"current_score": 7.5,
"previous_date": "2026-03-22",
"previous_score": 6.8,
"score_delta": 0.7,
"new_findings": 2,
"resolved_findings": 5,
"direction": "improving",
"history": [
{ "date": "2026-03-15", "score": 5.2, "total_findings": 45 },
{ "date": "2026-03-22", "score": 6.8, "total_findings": 32 },
{ "date": "2026-03-29", "score": 7.5, "total_findings": 29 }
]
}
}Direction values:
| Direction | Condition |
|---|---|
improving | score_delta > 0.5 |
stable | -0.5 <= score_delta <= 0.5 |
regressing | score_delta < -0.5 |
baseline | No previous audit exists |
Finding Deduplication
When the same vulnerability appears in multiple phases: 1. Keep the highest-severity classification 2. Merge evidence from all phases 3. Count as a single finding for scoring 4. Note all phases that detected it