mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-18 21:49:40 +03:00
Production hardening: security fixes, code quality, 724 skills complete
- 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
This commit is contained in:
+188
-16
@@ -1,29 +1,201 @@
|
||||
# API Reference: Vulnerability SLA breach alerting agent
|
||||
# API Reference: Vulnerability SLA Breach Alerting
|
||||
|
||||
## API Details
|
||||
SLA calculation, SMTP notification, Slack webhook, Jira ticket creation
|
||||
## Libraries Used
|
||||
|
||||
| Library | Purpose |
|
||||
|---------|---------|
|
||||
| `requests` | Slack webhook and Jira API integration |
|
||||
| `smtplib` | Send email alerts for SLA breaches |
|
||||
| `json` | Parse vulnerability and SLA data |
|
||||
| `datetime` | Calculate SLA deadlines and breach timing |
|
||||
| `email.mime.text` | Compose HTML email notifications |
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install requests smtplib datetime
|
||||
pip install requests
|
||||
```
|
||||
|
||||
## Libraries
|
||||
## Alert Channels
|
||||
|
||||
| Library | Use |
|
||||
|---------|-----|
|
||||
| `requests` | requests client/SDK |
|
||||
| `smtplib` | smtplib client/SDK |
|
||||
| `datetime` | datetime client/SDK |
|
||||
### Slack Webhook Alert
|
||||
```python
|
||||
import requests
|
||||
import os
|
||||
|
||||
## Authentication
|
||||
SLACK_WEBHOOK = os.environ["SLACK_WEBHOOK_URL"]
|
||||
|
||||
| Method | Header |
|
||||
|--------|--------|
|
||||
| Bearer Token | `Authorization: Bearer <token>` |
|
||||
| API Key | `X-API-Key: <key>` |
|
||||
def send_slack_alert(breaches):
|
||||
blocks = [
|
||||
{
|
||||
"type": "header",
|
||||
"text": {"type": "plain_text", "text": "SLA Breach Alert"}
|
||||
},
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": f"*{len(breaches)} vulnerabilities have breached SLA*",
|
||||
}
|
||||
},
|
||||
]
|
||||
for breach in breaches[:10]:
|
||||
blocks.append({
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": (
|
||||
f"*{breach['cve']}* — {breach['severity'].upper()}\n"
|
||||
f"Host: `{breach['host']}` | Overdue: {breach['hours_overdue']}h\n"
|
||||
f"Owner: {breach.get('owner', 'Unassigned')}"
|
||||
),
|
||||
}
|
||||
})
|
||||
|
||||
resp = requests.post(
|
||||
SLACK_WEBHOOK,
|
||||
json={"blocks": blocks},
|
||||
timeout=10,
|
||||
)
|
||||
return resp.status_code == 200
|
||||
```
|
||||
|
||||
### Email Alert (SMTP)
|
||||
```python
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
|
||||
def send_email_alert(breaches, recipients):
|
||||
smtp_host = os.environ["SMTP_HOST"]
|
||||
smtp_port = int(os.environ.get("SMTP_PORT", "587"))
|
||||
smtp_user = os.environ["SMTP_USER"]
|
||||
smtp_pass = os.environ["SMTP_PASS"]
|
||||
|
||||
msg = MIMEMultipart("alternative")
|
||||
msg["Subject"] = f"SLA Breach: {len(breaches)} vulnerabilities overdue"
|
||||
msg["From"] = smtp_user
|
||||
msg["To"] = ", ".join(recipients)
|
||||
|
||||
html = "<h2>SLA Breach Report</h2><table border='1'>"
|
||||
html += "<tr><th>CVE</th><th>Severity</th><th>Host</th><th>Hours Overdue</th></tr>"
|
||||
for b in breaches:
|
||||
html += f"<tr><td>{b['cve']}</td><td>{b['severity']}</td>"
|
||||
html += f"<td>{b['host']}</td><td>{b['hours_overdue']}</td></tr>"
|
||||
html += "</table>"
|
||||
|
||||
msg.attach(MIMEText(html, "html"))
|
||||
|
||||
with smtplib.SMTP(smtp_host, smtp_port) as server:
|
||||
server.starttls()
|
||||
server.login(smtp_user, smtp_pass)
|
||||
server.sendmail(smtp_user, recipients, msg.as_string())
|
||||
```
|
||||
|
||||
### Jira Ticket Creation
|
||||
```python
|
||||
JIRA_URL = os.environ["JIRA_URL"]
|
||||
JIRA_AUTH = (os.environ["JIRA_USER"], os.environ["JIRA_TOKEN"])
|
||||
|
||||
def create_jira_ticket(breach):
|
||||
ticket = {
|
||||
"fields": {
|
||||
"project": {"key": os.environ.get("JIRA_PROJECT", "VULN")},
|
||||
"summary": f"SLA Breach: {breach['cve']} on {breach['host']}",
|
||||
"description": (
|
||||
f"Vulnerability {breach['cve']} ({breach['severity']}) "
|
||||
f"has breached its remediation SLA.\n\n"
|
||||
f"Host: {breach['host']}\n"
|
||||
f"Hours overdue: {breach['hours_overdue']}\n"
|
||||
f"Discovery date: {breach['discovery_date']}\n"
|
||||
f"SLA deadline: {breach['deadline']}\n\n"
|
||||
f"Required action: Remediate immediately."
|
||||
),
|
||||
"issuetype": {"name": "Bug"},
|
||||
"priority": {"name": "Highest" if breach["severity"] == "critical" else "High"},
|
||||
"labels": ["sla-breach", "security", breach["severity"]],
|
||||
}
|
||||
}
|
||||
resp = requests.post(
|
||||
f"{JIRA_URL}/rest/api/2/issue",
|
||||
auth=JIRA_AUTH,
|
||||
json=ticket,
|
||||
timeout=30,
|
||||
)
|
||||
resp.raise_for_status()
|
||||
return resp.json()["key"]
|
||||
```
|
||||
|
||||
## SLA Breach Detection
|
||||
|
||||
```python
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
SLA_TIERS = {
|
||||
"critical": timedelta(hours=24),
|
||||
"high": timedelta(hours=72),
|
||||
"medium": timedelta(days=30),
|
||||
"low": timedelta(days=90),
|
||||
}
|
||||
|
||||
def detect_breaches(vulnerabilities):
|
||||
breaches = []
|
||||
now = datetime.now()
|
||||
for vuln in vulnerabilities:
|
||||
if vuln.get("remediated"):
|
||||
continue
|
||||
discovery = datetime.fromisoformat(vuln["discovery_date"])
|
||||
sla = SLA_TIERS.get(vuln["severity"].lower(), timedelta(days=90))
|
||||
deadline = discovery + sla
|
||||
if now > deadline:
|
||||
breaches.append({
|
||||
**vuln,
|
||||
"deadline": deadline.isoformat(),
|
||||
"hours_overdue": round((now - deadline).total_seconds() / 3600, 1),
|
||||
})
|
||||
return sorted(breaches, key=lambda b: b["hours_overdue"], reverse=True)
|
||||
```
|
||||
|
||||
## Orchestration
|
||||
|
||||
```python
|
||||
def run_sla_breach_alerting(vulnerabilities):
|
||||
breaches = detect_breaches(vulnerabilities)
|
||||
if not breaches:
|
||||
return {"breaches": 0, "alerts_sent": False}
|
||||
|
||||
# Send alerts through all channels
|
||||
send_slack_alert(breaches)
|
||||
send_email_alert(breaches, os.environ.get("ALERT_RECIPIENTS", "").split(","))
|
||||
|
||||
# Create Jira tickets for critical/high breaches only
|
||||
for breach in breaches:
|
||||
if breach["severity"] in ("critical", "high"):
|
||||
create_jira_ticket(breach)
|
||||
|
||||
return {"breaches": len(breaches), "alerts_sent": True}
|
||||
```
|
||||
|
||||
## Output Format
|
||||
|
||||
```json
|
||||
{"timestamp": "ISO-8601", "findings": [], "risk_level": "HIGH"}
|
||||
{
|
||||
"run_time": "2025-01-15T10:00:00Z",
|
||||
"breaches_detected": 5,
|
||||
"alerts": {
|
||||
"slack": true,
|
||||
"email": true,
|
||||
"jira_tickets_created": 3
|
||||
},
|
||||
"breaches": [
|
||||
{
|
||||
"cve": "CVE-2024-21887",
|
||||
"severity": "critical",
|
||||
"host": "web-prod-01",
|
||||
"hours_overdue": 48.5,
|
||||
"deadline": "2025-01-13T10:00:00",
|
||||
"owner": "platform-team"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user