Skip to main content

Agent Skills Framework Extension

Security Audit Patterns Skill

When to Use This Skill

Use this skill when implementing security audit patterns patterns in your codebase.

How to Use This Skill

  1. Review the patterns and examples below
  2. Apply the relevant patterns to your implementation
  3. Follow the best practices outlined in this skill

Comprehensive security audits covering OWASP Top 10, dependency vulnerabilities, threat modeling, and compliance validation.

Core Capabilities

  1. Vulnerability Assessment - OWASP Top 10 and CVE identification
  2. Dependency Auditing - Third-party package security
  3. Threat Modeling - Attack surface and risk analysis
  4. Compliance Reporting - Security standards validation
  5. Penetration Testing - Security testing coordination

Comprehensive Security Audit Script

#!/usr/bin/env python3
"""
Comprehensive security audit automation for web applications and APIs.
Covers OWASP Top 10, dependencies, configuration, and code security.
"""

import subprocess
import json
from pathlib import Path
from typing import List, Dict
from dataclasses import dataclass
from enum import Enum

class Severity(Enum):
CRITICAL = "critical"
HIGH = "high"
MEDIUM = "medium"
LOW = "low"
INFO = "info"

@dataclass
class SecurityFinding:
category: str
severity: Severity
title: str
description: str
cve: str = None
remediation: str = ""
affected_files: List[str] = None

class SecurityAuditor:
def __init__(self, project_path: Path):
self.project_path = project_path
self.findings: List[SecurityFinding] = []

def run_full_audit(self) -> Dict:
"""Execute comprehensive security audit."""
print("🔒 Starting comprehensive security audit...\n")

self.audit_dependencies()
self.audit_code_security()
self.audit_configuration()
self.audit_secrets()
self.audit_docker_security()

return self.generate_report()

def audit_dependencies(self):
"""Audit third-party dependencies for known vulnerabilities."""
print("📦 Auditing dependencies...")

# npm audit
if (self.project_path / "package.json").exists():
result = subprocess.run(
['npm', 'audit', '--json'],
cwd=self.project_path,
capture_output=True,
text=True
)

if result.returncode != 0:
audit_data = json.loads(result.stdout)
for vuln_id, vuln in audit_data.get('vulnerabilities', {}).items():
self.findings.append(SecurityFinding(
category='dependency',
severity=self._map_severity(vuln.get('severity', 'low')),
title=f"Vulnerable dependency: {vuln_id}",
description=vuln.get('title', ''),
cve=vuln.get('cves', [None])[0],
remediation=f"Update to version {vuln.get('fixAvailable', {}).get('version', 'latest')}"
))

# Python safety check
if (self.project_path / "requirements.txt").exists():
result = subprocess.run(
['safety', 'check', '--json'],
cwd=self.project_path,
capture_output=True,
text=True
)

if result.stdout:
vulns = json.loads(result.stdout)
for vuln in vulns:
self.findings.append(SecurityFinding(
category='dependency',
severity=Severity.HIGH,
title=f"Vulnerable package: {vuln['package']}",
description=vuln['vulnerability'],
cve=vuln.get('CVE'),
remediation=f"Update to version {vuln['secure_versions']}"
))

def audit_code_security(self):
"""Scan code for security anti-patterns."""
print("🔍 Scanning code for security issues...")

# Python: Bandit
if list(self.project_path.rglob("*.py")):
result = subprocess.run(
['bandit', '-r', '.', '-f', 'json'],
cwd=self.project_path,
capture_output=True,
text=True
)

if result.stdout:
data = json.loads(result.stdout)
for issue in data.get('results', []):
self.findings.append(SecurityFinding(
category='code-security',
severity=self._map_severity(issue['issue_severity'].lower()),
title=issue['issue_text'],
description=f"{issue['issue_text']} at {issue['filename']}:{issue['line_number']}",
remediation=issue.get('more_info', ''),
affected_files=[issue['filename']]
))

# JavaScript/TypeScript: eslint security plugin
if (self.project_path / ".eslintrc.json").exists():
result = subprocess.run(
['npm', 'run', 'lint', '--', '--format=json'],
cwd=self.project_path,
capture_output=True,
text=True
)

if result.stdout:
try:
lint_results = json.loads(result.stdout)
for file_result in lint_results:
for message in file_result.get('messages', []):
if 'security' in message.get('ruleId', '').lower():
self.findings.append(SecurityFinding(
category='code-security',
severity=self._map_severity(message['severity']),
title=message['message'],
description=f"{message['message']} in {file_result['filePath']}",
affected_files=[file_result['filePath']]
))
except json.JSONDecodeError:
pass

def audit_configuration(self):
"""Check security configuration."""
print("⚙️ Auditing security configuration...")

# Check for exposed secrets in config files
config_files = [
'.env', '.env.local', '.env.production',
'config.json', 'secrets.json'
]

for config_file in config_files:
if (self.project_path / config_file).exists():
self.findings.append(SecurityFinding(
category='configuration',
severity=Severity.CRITICAL,
title=f"Sensitive configuration file in repository: {config_file}",
description=f"Configuration file {config_file} should not be committed to version control",
remediation=f"Add {config_file} to .gitignore and use environment variables or secret management",
affected_files=[config_file]
))

# Check SSL/TLS configuration
if (self.project_path / "nginx.conf").exists():
content = (self.project_path / "nginx.conf").read_text()
if 'ssl_protocols' not in content or 'TLSv1.2' not in content:
self.findings.append(SecurityFinding(
category='configuration',
severity=Severity.HIGH,
title="Weak TLS configuration",
description="nginx configuration missing strong TLS protocols",
remediation="Add: ssl_protocols TLSv1.2 TLSv1.3;",
affected_files=["nginx.conf"]
))

def audit_secrets(self):
"""Scan for accidentally committed secrets."""
print("🔐 Scanning for committed secrets...")

# Use git-secrets or gitleaks
try:
result = subprocess.run(
['gitleaks', 'detect', '--no-git', '--report-format=json', '--report-path=-'],
cwd=self.project_path,
capture_output=True,
text=True
)

if result.stdout:
leaks = json.loads(result.stdout)
for leak in leaks:
self.findings.append(SecurityFinding(
category='secrets',
severity=Severity.CRITICAL,
title=f"Secret detected: {leak.get('RuleID', 'unknown')}",
description=f"Secret found in {leak.get('File', 'unknown')} at line {leak.get('StartLine', 0)}",
remediation="Remove secret from repository history and rotate credentials",
affected_files=[leak.get('File')]
))
except FileNotFoundError:
print(" ⚠️ gitleaks not installed, skipping secret scanning")

def audit_docker_security(self):
"""Audit Docker configuration security."""
print("🐳 Auditing Docker security...")

dockerfile_path = self.project_path / "Dockerfile"
if not dockerfile_path.exists():
return

content = dockerfile_path.read_text()

# Check for running as root
if 'USER' not in content:
self.findings.append(SecurityFinding(
category='docker',
severity=Severity.HIGH,
title="Container running as root user",
description="Dockerfile does not specify non-root USER",
remediation="Add non-root user: RUN useradd -m appuser && USER appuser",
affected_files=["Dockerfile"]
))

# Check for latest tag
if ':latest' in content or 'FROM alpine\n' in content:
self.findings.append(SecurityFinding(
category='docker',
severity=Severity.MEDIUM,
title="Using :latest tag in base image",
description="Base image using :latest tag is not pinned to specific version",
remediation="Pin to specific version: FROM alpine:3.18",
affected_files=["Dockerfile"]
))

def _map_severity(self, severity: str) -> Severity:
"""Map severity string to enum."""
severity_map = {
'critical': Severity.CRITICAL,
'high': Severity.HIGH,
'medium': Severity.MEDIUM,
'low': Severity.LOW,
'info': Severity.INFO,
'moderate': Severity.MEDIUM,
'1': Severity.LOW,
'2': Severity.HIGH
}
return severity_map.get(severity.lower(), Severity.INFO)

def generate_report(self) -> Dict:
"""Generate security audit report."""
# Group by severity
by_severity = {}
for finding in self.findings:
sev = finding.severity.value
if sev not in by_severity:
by_severity[sev] = []
by_severity[sev].append(finding)

# Calculate metrics
total = len(self.findings)
critical = len(by_severity.get('critical', []))
high = len(by_severity.get('high', []))
medium = len(by_severity.get('medium', []))
low = len(by_severity.get('low', []))

report = {
'summary': {
'total_findings': total,
'critical': critical,
'high': high,
'medium': medium,
'low': low,
'risk_score': (critical * 10 + high * 5 + medium * 3 + low * 1)
},
'findings': [
{
'category': f.category,
'severity': f.severity.value,
'title': f.title,
'description': f.description,
'cve': f.cve,
'remediation': f.remediation,
'affected_files': f.affected_files
}
for f in self.findings
]
}

# Save JSON report
report_path = self.project_path / 'security-audit-report.json'
with open(report_path, 'w') as f:
json.dump(report, f, indent=2)

# Generate Markdown report
md_report = self._generate_markdown_report(report)
md_path = self.project_path / 'security-audit-report.md'
with open(md_path, 'w') as f:
f.write(md_report)

print(f"\n📊 Security Audit Summary:")
print(f" Total Findings: {total}")
print(f" Critical: {critical}")
print(f" High: {high}")
print(f" Medium: {medium}")
print(f" Low: {low}")
print(f" Risk Score: {report['summary']['risk_score']}")
print(f"\n📄 Reports generated:")
print(f" JSON: {report_path}")
print(f" Markdown: {md_path}")

return report

def _generate_markdown_report(self, report: Dict) -> str:
"""Generate Markdown security report."""
md = "# Security Audit Report\n\n"
md += "## Summary\n\n"
md += f"- **Total Findings:** {report['summary']['total_findings']}\n"
md += f"- **Critical:** {report['summary']['critical']}\n"
md += f"- **High:** {report['summary']['high']}\n"
md += f"- **Medium:** {report['summary']['medium']}\n"
md += f"- **Low:** {report['summary']['low']}\n"
md += f"- **Risk Score:** {report['summary']['risk_score']}\n\n"

# Group findings by severity
for severity in ['critical', 'high', 'medium', 'low']:
findings = [f for f in report['findings'] if f['severity'] == severity]
if findings:
md += f"## {severity.upper()} ({len(findings)})\n\n"
for i, finding in enumerate(findings, 1):
md += f"### {i}. {finding['title']}\n\n"
md += f"- **Category:** {finding['category']}\n"
md += f"- **Description:** {finding['description']}\n"
if finding['cve']:
md += f"- **CVE:** {finding['cve']}\n"
md += f"- **Remediation:** {finding['remediation']}\n"
if finding['affected_files']:
md += f"- **Affected Files:** {', '.join(finding['affected_files'])}\n"
md += "\n"

return md

# CLI usage
if __name__ == '__main__':
import sys

path = Path(sys.argv[1]) if len(sys.argv) > 1 else Path.cwd()

auditor = SecurityAuditor(path)
report = auditor.run_full_audit()

# Exit with error if critical or high severity findings
if report['summary']['critical'] > 0 or report['summary']['high'] > 0:
print(f"\n❌ Security audit failed: {report['summary']['critical']} critical, {report['summary']['high']} high severity issues")
sys.exit(1)
else:
print("\n✅ Security audit passed")

OWASP Top 10 Checklist

# owasp-top-10-checklist.yaml
# OWASP Top 10 2021 security verification checklist

A01_BrokenAccessControl:
- Enforce least privilege access control
- Deny by default for all resources
- Validate JWT tokens and session management
- Rate limiting on sensitive endpoints
- CORS configuration review

A02_CryptographicFailures:
- TLS 1.2+ for all connections
- Strong cipher suites only
- Sensitive data encrypted at rest
- Key rotation policy implemented
- Password hashing with bcrypt/Argon2

A03_Injection:
- Parameterized queries for SQL
- Input validation and sanitization
- Content Security Policy headers
- Command injection prevention
- NoSQL injection protection

A04_InsecureDesign:
- Threat modeling conducted
- Security requirements defined
- Secure development lifecycle
- Design patterns review
- Attack surface minimization

A05_SecurityMisconfiguration:
- Default credentials removed
- Unnecessary features disabled
- Security headers configured
- Error messages sanitized
- Dependency versions pinned

A06_VulnerableComponents:
- Dependency scanning automated
- Regular security updates
- Component inventory maintained
- Third-party library audit
- Supply chain security

A07_IdentificationAuthenticationFailures:
- Multi-factor authentication enabled
- Strong password policy
- Session timeout configured
- Account lockout after failed attempts
- Credential stuffing protection

A08_SoftwareDataIntegrityFailures:
- Code signing implemented
- CI/CD pipeline security
- Artifact integrity verification
- Digital signatures validated
- Unsigned code rejected

A09_SecurityLoggingMonitoringFailures:
- Comprehensive audit logging
- Security event monitoring
- Anomaly detection configured
- Incident response plan
- Log integrity protection

A10_ServerSideRequestForgery:
- URL validation and sanitization
- Network segmentation
- Whitelist allowed destinations
- Disable HTTP redirections
- Response validation

Usage Examples

Full Security Audit

Apply security-audit-patterns skill to execute comprehensive security audit covering OWASP Top 10, dependencies, and configuration

Dependency Vulnerability Scan

Apply security-audit-patterns skill to audit third-party dependencies for known CVEs using npm audit and Safety

OWASP Compliance Check

Apply security-audit-patterns skill to validate application against OWASP Top 10 2021 checklist

Success Output

When successful, this skill MUST output:

✅ SKILL COMPLETE: security-audit-patterns

Completed:
- [x] Dependency vulnerabilities scanned (npm audit + Safety)
- [x] Code security analyzed (Bandit + ESLint security)
- [x] Configuration audited (SSL/TLS, secrets, Docker)
- [x] OWASP Top 10 compliance verified
- [x] Security reports generated

Outputs:
- security-audit-report.json (detailed findings)
- security-audit-report.md (human-readable)
- Risk score: [calculated value]
- Critical findings: [count]
- High findings: [count]

Total Findings: [X] (Critical: [Y], High: [Z], Medium: [A], Low: [B])

Completion Checklist

Before marking this skill as complete, verify:

  • All dependency scanners executed (npm audit, Safety, or equivalent)
  • Code security tools run (Bandit for Python, ESLint security for JS/TS)
  • Configuration files audited (.env, nginx.conf, Dockerfile)
  • Secret scanning completed (gitleaks or git-secrets)
  • Docker security checks performed (if applicable)
  • Both JSON and Markdown reports generated
  • Risk score calculated and documented
  • All critical and high severity findings documented with remediation steps

Failure Indicators

This skill has FAILED if:

  • ❌ No security report files generated
  • ❌ Dependency scanners not installed and script exited
  • ❌ Risk score not calculated or missing
  • ❌ Critical vulnerabilities found but no remediation steps provided
  • ❌ OWASP Top 10 checklist not validated
  • ❌ Reports contain placeholder data instead of actual findings

When NOT to Use

Do NOT use this skill when:

  • Performing quick syntax/linting checks only (use code-quality-patterns instead)
  • Conducting penetration testing (use penetration-testing-patterns instead)
  • Validating regulatory compliance only (use compliance-validation instead)
  • Scanning infrastructure (use infrastructure-security-patterns instead)
  • Auditing cloud configurations (use cloud-security-patterns instead)

Use these alternatives instead:

  • For quick security checks: security-quick-scan skill
  • For compliance-only: compliance-validation skill
  • For penetration testing: penetration-testing-patterns skill
  • For infrastructure: infrastructure-security-patterns skill

Anti-Patterns (Avoid)

Anti-PatternProblemSolution
Running audit without installing toolsScript fails, no resultsCheck for tools first, install if missing
Ignoring exit codesFalse positives, missed vulnerabilitiesAlways check scanner exit codes
Skipping secret scanningCommitted secrets go undetectedAlways run gitleaks/git-secrets
Not documenting remediationFindings without fixes are uselessInclude remediation for every finding
Running on production onlyIssues discovered too lateIntegrate into CI/CD for early detection
Using :latest in Docker base imagesUnpinned versions, security driftPin to specific versions (e.g., alpine:3.18)
Running as root in containersPrivilege escalation riskAdd non-root USER to Dockerfile

Principles

This skill embodies:

  • #5 Eliminate Ambiguity - Clear severity classification (CRITICAL/HIGH/MEDIUM/LOW)
  • #6 Clear, Understandable, Explainable - Structured reports with remediation guidance
  • #8 No Assumptions - Verify tool availability before execution
  • #2 First Principles - Security from OWASP foundations, not opinions
  • #9 Research When in Doubt - Reference CVE databases and security advisories

Security-First Mindset: This skill fails fast on critical/high severity issues (exit code 1) to prevent insecure deployments.

Integration Points

  • security-scanning-patterns - Automated security scanning
  • penetration-testing-patterns - Security testing
  • compliance-validation - Regulatory compliance