Skip to content

Commit 76ff769

Browse files
author
The-XSS-Rat
authored
Merge pull request #8 from The-XSS-Rat/codex/add-1000-scanning-rules-to-api-engine
Add bulk API regex ruleset generator and templates
2 parents dcc5736 + 026b124 commit 76ff769

File tree

2 files changed

+23189
-0
lines changed

2 files changed

+23189
-0
lines changed
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
"""Utility for generating bulk API regex scanning templates."""
2+
3+
from __future__ import annotations
4+
5+
import json
6+
from pathlib import Path
7+
from typing import Iterable
8+
9+
REPO_ROOT = Path(__file__).resolve().parent.parent
10+
TEMPLATE_PATH = REPO_ROOT / "automations" / "templates.json"
11+
12+
13+
BASE_SEVERITY = {
14+
"critical": ["critical", "high", "high", "medium"],
15+
"high": ["high", "high", "medium", "medium"],
16+
"medium": ["medium", "medium", "low", "medium"],
17+
}
18+
19+
CATEGORIES = [
20+
"access-management",
21+
"accounting",
22+
"analytics",
23+
"audit",
24+
"billing",
25+
"business-intelligence",
26+
"cloud-ops",
27+
"collaboration",
28+
"commerce",
29+
"compliance",
30+
"customer-success",
31+
"devops",
32+
"finance",
33+
"governance",
34+
"identity",
35+
"infrastructure",
36+
"logistics",
37+
"marketing",
38+
"operations",
39+
"product",
40+
]
41+
42+
EXPOSURES = [
43+
{
44+
"slug": "token-cache",
45+
"title": "Token Cache Dump",
46+
"path_template": "/api/{category_slug}/token-cache-{index_padded}.json",
47+
"description": "Detects exposed {category_title} token cache exports leaking bearer secrets.",
48+
"severity": "high",
49+
"regex_terms": ["token", "secret", "bearer"],
50+
"tags": ["api", "credentials", "{category_slug}"],
51+
},
52+
{
53+
"slug": "session-ledger",
54+
"title": "Session Ledger Leak",
55+
"path_template": "/api/{category_slug}/sessions-ledger-{index_padded}.log",
56+
"description": "Catches leaked {category_title} session ledgers disclosing JWTs and expirations.",
57+
"severity": "high",
58+
"regex_terms": ["session", "jwt", "exp"],
59+
"tags": ["api", "sessions", "{category_slug}"],
60+
},
61+
{
62+
"slug": "config-export",
63+
"title": "Config Export Exposure",
64+
"path_template": "/api/{category_slug}/config-export-{index_padded}.yaml",
65+
"description": "Finds world-readable {category_title} configuration exports exposing environment secrets.",
66+
"severity": "high",
67+
"regex_terms": ["config", "environment", "secret"],
68+
"tags": ["api", "config", "{category_slug}"],
69+
},
70+
{
71+
"slug": "user-dump",
72+
"title": "User Dump Exposure",
73+
"path_template": "/api/{category_slug}/user-dump-{index_padded}.csv",
74+
"description": "Detects exposed {category_title} user exports leaking directory records.",
75+
"severity": "medium",
76+
"regex_terms": ["email", "user", "id"],
77+
"tags": ["api", "intel", "{category_slug}"],
78+
},
79+
{
80+
"slug": "billing-export",
81+
"title": "Billing Export Exposure",
82+
"path_template": "/api/{category_slug}/billing-export-{index_padded}.csv",
83+
"description": "Identifies {category_title} billing exports containing transaction data.",
84+
"severity": "medium",
85+
"regex_terms": ["invoice", "amount", "currency"],
86+
"tags": ["api", "billing", "{category_slug}"],
87+
},
88+
{
89+
"slug": "webhook-registry",
90+
"title": "Webhook Registry Leak",
91+
"path_template": "/api/{category_slug}/webhooks-registry-{index_padded}.json",
92+
"description": "Detects leaked {category_title} webhook registries exposing callback secrets.",
93+
"severity": "high",
94+
"regex_terms": ["webhook", "callback", "signature"],
95+
"tags": ["api", "integrations", "{category_slug}"],
96+
},
97+
{
98+
"slug": "telemetry-snapshot",
99+
"title": "Telemetry Snapshot Exposure",
100+
"path_template": "/api/{category_slug}/telemetry-snapshot-{index_padded}.json",
101+
"description": "Surfaces exposed {category_title} telemetry snapshots leaking internal metrics.",
102+
"severity": "medium",
103+
"regex_terms": ["telemetry", "metric", "timestamp"],
104+
"tags": ["api", "telemetry", "{category_slug}"],
105+
},
106+
{
107+
"slug": "debug-trace",
108+
"title": "Debug Trace Log Leak",
109+
"path_template": "/api/{category_slug}/debug-trace-{index_padded}.log",
110+
"description": "Detects leaked {category_title} debug traces revealing stack data.",
111+
"severity": "medium",
112+
"regex_terms": ["trace", "exception", "stack"],
113+
"tags": ["api", "debug", "{category_slug}"],
114+
},
115+
{
116+
"slug": "database-backup",
117+
"title": "Database Backup Exposure",
118+
"path_template": "/api/{category_slug}/db-backup-{index_padded}.sql",
119+
"description": "Finds exposed {category_title} database backups with raw records.",
120+
"severity": "high",
121+
"regex_terms": ["insert", "password", "api_key"],
122+
"tags": ["api", "database", "{category_slug}"],
123+
},
124+
{
125+
"slug": "compliance-report",
126+
"title": "Compliance Report Leak",
127+
"path_template": "/api/{category_slug}/compliance-report-{index_padded}.pdf",
128+
"description": "Detects leaked {category_title} compliance reports disclosing control evidence.",
129+
"severity": "medium",
130+
"regex_terms": ["compliance", "control", "finding"],
131+
"tags": ["api", "compliance", "{category_slug}"],
132+
},
133+
]
134+
135+
136+
def slugify(value: str) -> str:
137+
"""Return a filesystem and URL friendly slug."""
138+
cleaned = "".join(ch if ch.isalnum() else "-" for ch in value.lower())
139+
cleaned = "-".join(filter(None, cleaned.split("-")))
140+
return cleaned or "category"
141+
142+
143+
def build_templates(existing_ids: Iterable[str]) -> list[dict[str, object]]:
144+
templates: list[dict[str, object]] = []
145+
for category in CATEGORIES:
146+
category_slug = slugify(category)
147+
category_title = category.replace("-", " ").title()
148+
for exposure in EXPOSURES:
149+
severity_cycle = BASE_SEVERITY[exposure["severity"]]
150+
for index in range(1, 6):
151+
severity = severity_cycle[(index - 1) % len(severity_cycle)]
152+
context = {
153+
"category": category,
154+
"category_slug": category_slug,
155+
"category_title": category_title,
156+
"index": index,
157+
"index_padded": f"{index:02d}",
158+
}
159+
template_id = f"api-regex-{exposure['slug']}-{category_slug}-{index:02d}"
160+
if template_id in existing_ids:
161+
continue
162+
template = {
163+
"id": template_id,
164+
"name": f"{category_title} {exposure['title']} #{index}",
165+
"description": exposure["description"].format(**context),
166+
"severity": severity,
167+
"method": "GET",
168+
"path": exposure["path_template"].format(**context),
169+
"matchers": {
170+
"status": [200],
171+
"regex": [f"(?i){term}" for term in exposure["regex_terms"]],
172+
},
173+
"tags": [tag.format(**context) for tag in exposure["tags"]],
174+
}
175+
templates.append(template)
176+
return templates
177+
178+
179+
def main() -> None:
180+
payload = json.loads(TEMPLATE_PATH.read_text())
181+
existing_ids = {entry.get("id") for entry in payload if isinstance(entry, dict)}
182+
additions = build_templates(existing_ids)
183+
payload.extend(additions)
184+
TEMPLATE_PATH.write_text(json.dumps(payload, indent=2))
185+
print(f"Added {len(additions)} templates. Total now {len(payload)}")
186+
187+
188+
if __name__ == "__main__":
189+
main()

0 commit comments

Comments
 (0)