mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-16 20:55:17 +03:00
c47eed6a64
- Fix 25 shell=True subprocess calls with list-based commands - Fix 49 verify=False in defensive skills (env-var override) - Add timeout to 231 HTTP/subprocess/socket calls - Fix 6 SQL injection patterns with whitelist validation - Replace 8 __import__() with standard imports - Remove 701 unused imports across 442 files - Add authorized-testing disclaimers to all offensive skills - Complete 11 incomplete skill directories - Expand 10 stub SKILL.md files with full content - Fix 2 YAML parse errors in frontmatter - Fix 5 pre-existing syntax errors - Convert 22 hardcoded paths/ports to environment variables - Back up 21 redundant skill pairs to .bak - Fix 2 global declaration errors - 724/724 skills with full folder anatomy (SKILL.md + agent.py + api-reference.md + LICENSE) - 0 compile errors across all 724 agent.py files
205 lines
7.6 KiB
Python
205 lines
7.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Agent for threat modeling with OWASP Threat Dragon.
|
|
|
|
Programmatically creates Threat Dragon JSON threat models, applies
|
|
STRIDE analysis to DFD elements, manages threat inventory, and
|
|
generates summary reports for security design reviews.
|
|
"""
|
|
|
|
import json
|
|
import sys
|
|
import uuid
|
|
from datetime import datetime
|
|
|
|
|
|
STRIDE_BY_ELEMENT = {
|
|
"process": ["Spoofing", "Tampering", "Repudiation",
|
|
"Information Disclosure", "Denial of Service",
|
|
"Elevation of Privilege"],
|
|
"data_store": ["Tampering", "Information Disclosure",
|
|
"Denial of Service"],
|
|
"data_flow": ["Tampering", "Information Disclosure",
|
|
"Denial of Service"],
|
|
"external_entity": ["Spoofing", "Repudiation"],
|
|
}
|
|
|
|
STRIDE_MITIGATIONS = {
|
|
"Spoofing": ["Implement strong authentication (MFA)",
|
|
"Use mutual TLS for service-to-service"],
|
|
"Tampering": ["Use integrity checks (HMAC, digital signatures)",
|
|
"Implement input validation"],
|
|
"Repudiation": ["Enable comprehensive audit logging",
|
|
"Use tamper-evident log storage"],
|
|
"Information Disclosure": ["Encrypt data at rest and in transit",
|
|
"Implement least-privilege access"],
|
|
"Denial of Service": ["Implement rate limiting",
|
|
"Use auto-scaling and circuit breakers"],
|
|
"Elevation of Privilege": ["Enforce RBAC and least privilege",
|
|
"Validate authorization on every request"],
|
|
}
|
|
|
|
|
|
class ThreatModelAgent:
|
|
"""Creates and manages OWASP Threat Dragon threat models."""
|
|
|
|
def __init__(self, title, owner="Security Team", description=""):
|
|
self.model = {
|
|
"version": "2.2.0",
|
|
"summary": {
|
|
"title": title,
|
|
"owner": owner,
|
|
"description": description,
|
|
"id": 0,
|
|
},
|
|
"detail": {
|
|
"contributors": [],
|
|
"diagrams": [],
|
|
"diagramTop": 0,
|
|
"reviewer": "",
|
|
"threatTop": 0,
|
|
},
|
|
}
|
|
self.threats = []
|
|
self.threat_counter = 0
|
|
|
|
def add_diagram(self, title, diagram_type="STRIDE"):
|
|
"""Add a new data flow diagram to the threat model."""
|
|
diagram_id = len(self.model["detail"]["diagrams"])
|
|
diagram = {
|
|
"id": diagram_id,
|
|
"title": title,
|
|
"diagramType": diagram_type,
|
|
"placeholder": f"New {diagram_type} diagram",
|
|
"thumbnail": "",
|
|
"version": "2.2.0",
|
|
"cells": [],
|
|
}
|
|
self.model["detail"]["diagrams"].append(diagram)
|
|
return diagram_id
|
|
|
|
def add_element(self, diagram_id, element_type, name,
|
|
x=100, y=100, description=""):
|
|
"""Add a DFD element to a diagram."""
|
|
element_id = str(uuid.uuid4())
|
|
type_map = {
|
|
"process": "tm.Process",
|
|
"data_store": "tm.Store",
|
|
"data_flow": "tm.Flow",
|
|
"external_entity": "tm.Actor",
|
|
"trust_boundary": "tm.Boundary",
|
|
}
|
|
cell = {
|
|
"type": type_map.get(element_type, "tm.Process"),
|
|
"id": element_id,
|
|
"name": name,
|
|
"description": description,
|
|
"position": {"x": x, "y": y},
|
|
"size": {"width": 100, "height": 60},
|
|
"threats": [],
|
|
"hasOpenThreats": False,
|
|
}
|
|
self.model["detail"]["diagrams"][diagram_id]["cells"].append(cell)
|
|
return element_id
|
|
|
|
def apply_stride(self, diagram_id, element_id, element_type):
|
|
"""Apply STRIDE analysis to a DFD element and generate threats."""
|
|
categories = STRIDE_BY_ELEMENT.get(element_type, [])
|
|
generated = []
|
|
diagram = self.model["detail"]["diagrams"][diagram_id]
|
|
element = next((c for c in diagram["cells"] if c["id"] == element_id), None)
|
|
if not element:
|
|
return []
|
|
|
|
for category in categories:
|
|
self.threat_counter += 1
|
|
threat = {
|
|
"id": str(self.threat_counter),
|
|
"title": f"{category} - {element['name']}",
|
|
"type": category,
|
|
"status": "Open",
|
|
"severity": "Medium",
|
|
"description": f"Potential {category.lower()} threat "
|
|
f"against {element['name']}",
|
|
"mitigation": "; ".join(
|
|
STRIDE_MITIGATIONS.get(category, ["Review required"])),
|
|
"modelType": "STRIDE",
|
|
"element_id": element_id,
|
|
}
|
|
element["threats"].append(threat)
|
|
element["hasOpenThreats"] = True
|
|
self.threats.append(threat)
|
|
generated.append(threat)
|
|
|
|
self.model["detail"]["threatTop"] = self.threat_counter
|
|
return generated
|
|
|
|
def update_threat_status(self, threat_id, status, mitigation=None):
|
|
"""Update a threat's status (Open, Mitigated, Not Applicable)."""
|
|
for threat in self.threats:
|
|
if threat["id"] == str(threat_id):
|
|
threat["status"] = status
|
|
if mitigation:
|
|
threat["mitigation"] = mitigation
|
|
return threat
|
|
return None
|
|
|
|
def get_threat_summary(self):
|
|
"""Summarize threats by status and category."""
|
|
summary = {"total": len(self.threats), "by_status": {},
|
|
"by_type": {}, "by_severity": {}}
|
|
for t in self.threats:
|
|
summary["by_status"][t["status"]] = \
|
|
summary["by_status"].get(t["status"], 0) + 1
|
|
summary["by_type"][t["type"]] = \
|
|
summary["by_type"].get(t["type"], 0) + 1
|
|
summary["by_severity"][t["severity"]] = \
|
|
summary["by_severity"].get(t["severity"], 0) + 1
|
|
return summary
|
|
|
|
def save_model(self, output_path):
|
|
"""Save the threat model as Threat Dragon JSON file."""
|
|
with open(output_path, "w") as f:
|
|
json.dump(self.model, f, indent=2)
|
|
return output_path
|
|
|
|
def generate_report(self):
|
|
"""Generate threat model assessment report."""
|
|
summary = self.get_threat_summary()
|
|
report = {
|
|
"title": self.model["summary"]["title"],
|
|
"owner": self.model["summary"]["owner"],
|
|
"report_date": datetime.utcnow().isoformat(),
|
|
"diagrams": len(self.model["detail"]["diagrams"]),
|
|
"threat_summary": summary,
|
|
"open_threats": [t for t in self.threats if t["status"] == "Open"],
|
|
"mitigated_threats": [t for t in self.threats
|
|
if t["status"] == "Mitigated"],
|
|
}
|
|
print(json.dumps(report, indent=2))
|
|
return report
|
|
|
|
|
|
def main():
|
|
title = sys.argv[1] if len(sys.argv) > 1 else "Sample Application"
|
|
output = sys.argv[2] if len(sys.argv) > 2 else "./threat_model.json"
|
|
|
|
agent = ThreatModelAgent(title, owner="Security Team",
|
|
description="Automated threat model")
|
|
did = agent.add_diagram("Main Data Flow")
|
|
web = agent.add_element(did, "external_entity", "Web Browser", 50, 50)
|
|
api = agent.add_element(did, "process", "API Gateway", 250, 50)
|
|
db = agent.add_element(did, "data_store", "Database", 450, 50)
|
|
flow1 = agent.add_element(did, "data_flow", "HTTPS Request", 150, 100)
|
|
|
|
agent.apply_stride(did, web, "external_entity")
|
|
agent.apply_stride(did, api, "process")
|
|
agent.apply_stride(did, db, "data_store")
|
|
agent.apply_stride(did, flow1, "data_flow")
|
|
|
|
agent.save_model(output)
|
|
agent.generate_report()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|