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
- Review the patterns and examples below
- Apply the relevant patterns to your implementation
- Follow the best practices outlined in this skill
Comprehensive security audits covering OWASP Top 10, dependency vulnerabilities, threat modeling, and compliance validation.
Core Capabilities
- Vulnerability Assessment - OWASP Top 10 and CVE identification
- Dependency Auditing - Third-party package security
- Threat Modeling - Attack surface and risk analysis
- Compliance Reporting - Security standards validation
- 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-patternsinstead) - Conducting penetration testing (use
penetration-testing-patternsinstead) - Validating regulatory compliance only (use
compliance-validationinstead) - Scanning infrastructure (use
infrastructure-security-patternsinstead) - Auditing cloud configurations (use
cloud-security-patternsinstead)
Use these alternatives instead:
- For quick security checks:
security-quick-scanskill - For compliance-only:
compliance-validationskill - For penetration testing:
penetration-testing-patternsskill - For infrastructure:
infrastructure-security-patternsskill
Anti-Patterns (Avoid)
| Anti-Pattern | Problem | Solution |
|---|---|---|
| Running audit without installing tools | Script fails, no results | Check for tools first, install if missing |
| Ignoring exit codes | False positives, missed vulnerabilities | Always check scanner exit codes |
| Skipping secret scanning | Committed secrets go undetected | Always run gitleaks/git-secrets |
| Not documenting remediation | Findings without fixes are useless | Include remediation for every finding |
| Running on production only | Issues discovered too late | Integrate into CI/CD for early detection |
| Using :latest in Docker base images | Unpinned versions, security drift | Pin to specific versions (e.g., alpine:3.18) |
| Running as root in containers | Privilege escalation risk | Add 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