blitzstrike 2.4.190 → 2.4.191
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/index.js +31 -0
- package/intelligence/ab-signals.json +228 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,16 @@ All notable changes to Blitz Strike are documented here.
|
|
|
5
5
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
7
|
|
|
8
|
+
## [2.4.191] — 2026-11-03
|
|
9
|
+
|
|
10
|
+
### Added — finding→next-action knowledge base (ab-signals)
|
|
11
|
+
|
|
12
|
+
- New `intelligence/ab-signals.json` (17 vuln classes) + `ab_signal` / list-all tool:
|
|
13
|
+
per class, how to CONFIRM it (proof_oracle = differential/timing/oob + test_vectors
|
|
14
|
+
+ negative_control), what to suppress (negative_keywords), what to try next
|
|
15
|
+
(followup), what it chains into (chain_with), and when to STOP (kill_conditions).
|
|
16
|
+
The kill_conditions + proof_oracle fields are new (not in chains.json/attack_vectors).
|
|
17
|
+
|
|
8
18
|
## [2.4.190] — 2026-11-03
|
|
9
19
|
|
|
10
20
|
### Added — 4 anti-false-positive doctrine rules (PentestGPT + xalgorix + Dark-Moon + airecon)
|
package/dist/index.js
CHANGED
|
@@ -35795,6 +35795,26 @@ function taxonomy(kind, query) {
|
|
|
35795
35795
|
usage: "taxonomy(kind='web'|'api'|'cwe'|'asvs', query?)"
|
|
35796
35796
|
};
|
|
35797
35797
|
}
|
|
35798
|
+
function listAbSignalClasses() {
|
|
35799
|
+
const data = loadJson("ab-signals");
|
|
35800
|
+
if (!data)
|
|
35801
|
+
return { error: "ab-signals.json not found" };
|
|
35802
|
+
return {
|
|
35803
|
+
classes: data.classes.map((c) => ({ class: c.class, name: c.name, cwe: c.cwe, proof_oracle: c.proof_oracle }))
|
|
35804
|
+
};
|
|
35805
|
+
}
|
|
35806
|
+
function abSignal(classOrKeyword) {
|
|
35807
|
+
const data = loadJson("ab-signals");
|
|
35808
|
+
if (!data)
|
|
35809
|
+
return { found: false, error: "ab-signals.json not found" };
|
|
35810
|
+
const q = classOrKeyword.trim().toLowerCase();
|
|
35811
|
+
if (!q)
|
|
35812
|
+
return { found: false, error: "pass a vuln class (sqli/xss/ssrf/idor/ssti/rce/...) or keyword" };
|
|
35813
|
+
const hit = data.classes.find((c) => c.class.toLowerCase() === q || c.name.toLowerCase().includes(q) || c.keywords.some((k) => k.toLowerCase().includes(q) || q.includes(k.toLowerCase())));
|
|
35814
|
+
if (hit)
|
|
35815
|
+
return { found: true, ...hit };
|
|
35816
|
+
return { found: false, query: classOrKeyword, suggestions: data.classes.map((c) => c.class) };
|
|
35817
|
+
}
|
|
35798
35818
|
|
|
35799
35819
|
// src/writeup.ts
|
|
35800
35820
|
var CHAIN_TO_CLASS = {
|
|
@@ -66697,6 +66717,17 @@ ${statusLine}` : statusLine },
|
|
|
66697
66717
|
}, async ({ cls }) => {
|
|
66698
66718
|
return { content: [{ type: "text", text: JSON.stringify(techniqueLookup(cls)) }] };
|
|
66699
66719
|
});
|
|
66720
|
+
server.registerTool("ab_signal", {
|
|
66721
|
+
title: "Finding → next-action knowledge base",
|
|
66722
|
+
description: "INTEL: return the deterministic finding→next-action entry for a vuln class (sqli/xss/ssrf/idor/ssti/rce/path_traversal/xxe/deserialization/csrf/jwt/open_redirect/auth_bypass/proto_pollution/nosql/crlf/file_upload): how to CONFIRM it (proof_oracle = differential/timing/oob + test_vectors + negative_control), what to suppress (negative_keywords), what to try NEXT (followup), what it CHAINS into (chain_with), and when to STOP (kill_conditions). Use right after you suspect or confirm a finding of that class — instead of reasoning 'what next' from scratch, one lookup gives confirm → chain → stop. Pass no arg to list all classes.",
|
|
66723
|
+
inputSchema: {
|
|
66724
|
+
cls: string2().optional().describe("Vuln class id or keyword (e.g. 'sqli', 'xss', 'idor', 'command injection').")
|
|
66725
|
+
}
|
|
66726
|
+
}, async ({ cls }) => {
|
|
66727
|
+
if (!cls)
|
|
66728
|
+
return { content: [{ type: "text", text: JSON.stringify(listAbSignalClasses()) }] };
|
|
66729
|
+
return { content: [{ type: "text", text: JSON.stringify(abSignal(cls)) }] };
|
|
66730
|
+
});
|
|
66700
66731
|
server.registerTool("framework_tricks", {
|
|
66701
66732
|
title: "Framework-specific exploitation tricks",
|
|
66702
66733
|
description: "INTEL: return framework-specific exploitation knowledge for a framework (Laravel, Django, Flask, Node/Express, Next.js, Vue, Angular, WordPress, Joomla, Spring, JSP, Python, Go, Ruby/Rails, Perl, GraphQL) — detection signals, known vulns/CVEs, and concrete attack tricks. Use after detect_framework to hunt that framework's specific weaknesses.",
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "blitzstrike-ab-signals-v1",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"_comment": "Finding -> next-action knowledge base. Per vuln class: how to CONFIRM it (proof_oracle + test_vectors + negative_control), what to suppress (negative_keywords), what to try NEXT (followup), what it CHAINS into (chain_with), and when to STOP (kill_conditions). proof_oracle ties to the verification-oracle doctrine: differential (attack diverges from control) / timing (induced delay clears noise floor) / oob (target calls back). kill_conditions is the missing piece: a vector with no growth past these is a dead end, not a 'keep trying'.",
|
|
5
|
+
"classes": [
|
|
6
|
+
{
|
|
7
|
+
"class": "sqli",
|
|
8
|
+
"name": "SQL Injection",
|
|
9
|
+
"cwe": "CWE-89",
|
|
10
|
+
"keywords": ["sql", "injection", "quote error", "syntax error", "database error", "mysql", "postgres", "oracle", "mssql", "sqlite"],
|
|
11
|
+
"negative_keywords": ["reflected in html", "echoed", "sanitized", "prepared statement", "parameterized", "orm"],
|
|
12
|
+
"proof_oracle": "differential",
|
|
13
|
+
"test_vectors": ["'", "\"", "' OR '1'='1", "1 AND 1=1", "1 AND 1=2", "' OR SLEEP(5)-- -"],
|
|
14
|
+
"negative_control": "1 AND 1=2 (must differ from 1 AND 1=1)",
|
|
15
|
+
"followup": ["extract version via union/error", "enumerate tables/columns", "read sensitive rows", "try time-based if blind"],
|
|
16
|
+
"chain_with": ["rce", "data_exposure", "auth_bypass"],
|
|
17
|
+
"kill_conditions": ["3 probes with zero differential and zero DB error", "input is a plain integer with no string concatenation", "WAF consistently blocks all quote variants"]
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"class": "xss",
|
|
21
|
+
"name": "Cross-Site Scripting",
|
|
22
|
+
"cwe": "CWE-79",
|
|
23
|
+
"keywords": ["xss", "reflected", "stored", "dom", "script injection", "html injection"],
|
|
24
|
+
"negative_keywords": ["encoded", "escaped", "sanitized", "csp", "content-security-policy"],
|
|
25
|
+
"proof_oracle": "differential",
|
|
26
|
+
"test_vectors": ["<script>alert(1)</script>", "<img src=x onerror=alert(1)>", "\"><svg/onload=alert(1)>", "javascript:alert(1)"],
|
|
27
|
+
"negative_control": "a harmless literal string must NOT be interpreted as markup",
|
|
28
|
+
"followup": ["test stored vs reflected", "check DOM sinks", "prove execution not reflection", "steal session cookie / token"],
|
|
29
|
+
"chain_with": ["account_takeover", "csrf"],
|
|
30
|
+
"kill_conditions": ["payload reflected but never executed (escaped/encoded)", "CSP blocks inline script with no bypass", "input is server-encoded in all contexts"]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"class": "ssrf",
|
|
34
|
+
"name": "Server-Side Request Forgery",
|
|
35
|
+
"cwe": "CWE-918",
|
|
36
|
+
"keywords": ["ssrf", "server-side request", "url fetch", "webhook", "proxy", "curl"],
|
|
37
|
+
"negative_keywords": ["client-side", "browser fetch", "ajax", "localhost blocked", "allowlist"],
|
|
38
|
+
"proof_oracle": "oob",
|
|
39
|
+
"test_vectors": ["http://169.254.169.254/latest/meta-data/", "http://127.0.0.1:8080", "http://[::1]", "gopher://127.0.0.1:6379/_"],
|
|
40
|
+
"negative_control": "a non-resolvable callback URL fires nothing while your real callback fires",
|
|
41
|
+
"followup": ["read cloud metadata (IMDS)", "hit internal services", "gopher/redis/FCGI chains", "confirm the target server (not you) made the request"],
|
|
42
|
+
"chain_with": ["rce", "data_exposure", "cloud_compromise"],
|
|
43
|
+
"kill_conditions": ["no callback despite correct interactsh setup and no egress filter", "strict host allowlist", "URL is fetched client-side not server-side"]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"class": "idor",
|
|
47
|
+
"name": "IDOR / BOLA / BFLA",
|
|
48
|
+
"cwe": "CWE-639",
|
|
49
|
+
"keywords": ["idor", "bola", "bfla", "object reference", "user id", "unauthorized access", "broken access control"],
|
|
50
|
+
"negative_keywords": ["own object", "scoped", "owner check", "authorization checked"],
|
|
51
|
+
"proof_oracle": "differential",
|
|
52
|
+
"test_vectors": ["swap id for another user's id", "swap uuid", "change role param", "cross-tenant id"],
|
|
53
|
+
"negative_control": "access your OWN object succeeds; another user's object must return 403/404",
|
|
54
|
+
"followup": ["prove protected DATA returned (not empty 200)", "test BFLA (function-level)", "test mass assignment", "test cross-tenant"],
|
|
55
|
+
"chain_with": ["data_exposure", "account_takeover", "priv_esc"],
|
|
56
|
+
"kill_conditions": ["cross-identity access returns 403/404", "a 200 with empty body is NOT access", "every object reference is server-scoped to the session"]
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"class": "ssti",
|
|
60
|
+
"name": "Server-Side Template Injection",
|
|
61
|
+
"cwe": "CWE-1336",
|
|
62
|
+
"keywords": ["ssti", "template injection", "jinja", "twig", "freemarker", "velocity", "thymeleaf"],
|
|
63
|
+
"negative_keywords": ["client-side template", "handlebars client", "angular"],
|
|
64
|
+
"proof_oracle": "differential",
|
|
65
|
+
"test_vectors": ["{{7*7}}", "${7*7}", "#{7*7}", "<%= 7*7 %>", "{{config}}"],
|
|
66
|
+
"negative_control": "a non-template literal (e.g. plain text) must be echoed unchanged",
|
|
67
|
+
"followup": ["confirm 49 (or product) evaluates server-side", "read config/secret", "reach os eval/exec for RCE"],
|
|
68
|
+
"chain_with": ["rce", "data_exposure"],
|
|
69
|
+
"kill_conditions": ["expression is echoed verbatim without evaluation", "template syntax is escaped", "no template engine detected"]
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"class": "rce",
|
|
73
|
+
"name": "Remote Code Execution / Command Injection",
|
|
74
|
+
"cwe": "CWE-78",
|
|
75
|
+
"keywords": ["rce", "command injection", "os command", "shell", "exec", "eval", "deserialization rce"],
|
|
76
|
+
"negative_keywords": ["escaped", "allowlist", "sandbox", "no shell"],
|
|
77
|
+
"proof_oracle": "timing",
|
|
78
|
+
"test_vectors": ["; id", "| whoami", "$(id)", "`id`", "&& sleep 5", "{{7*7}} (SSTI)", "ysoserial payload (deser)"],
|
|
79
|
+
"negative_control": "a harmless token must produce NO sleep and NO extra output",
|
|
80
|
+
"followup": ["establish quiet oracle (sleep/timing/OOB) BEFORE noisy payloads", "prove output from injected OS/runtime expression, not a fetch", "read /etc/passwd, whoami as read-only proof"],
|
|
81
|
+
"chain_with": ["data_exposure", "persistence", "pivot"],
|
|
82
|
+
"kill_conditions": ["no timing/OOB signal after 2 distinct primitives", "shell metacharacters are escaped/allowlisted", "execution is sandboxed with no escape"]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"class": "path_traversal",
|
|
86
|
+
"name": "Path Traversal / LFI",
|
|
87
|
+
"cwe": "CWE-22",
|
|
88
|
+
"keywords": ["path traversal", "lfi", "directory traversal", "include", "file read", "dot dot"],
|
|
89
|
+
"negative_keywords": ["whitelist", "basename", "realpath", "static file"],
|
|
90
|
+
"proof_oracle": "differential",
|
|
91
|
+
"test_vectors": ["../../../../etc/passwd", "..%2f..%2f..%2fetc/passwd", "....//....//etc/passwd", "..%252f..%252f", "php://filter/convert.base64-encode/resource=index.php"],
|
|
92
|
+
"negative_control": "a non-existent file must error differently than a readable one",
|
|
93
|
+
"followup": ["read sensitive files", "LFI to RCE via log poisoning / pearcmd / php://input", "confirm file CONTENT returned, not just an error change"],
|
|
94
|
+
"chain_with": ["rce", "data_exposure"],
|
|
95
|
+
"kill_conditions": ["path is normalized/allowlisted to a fixed directory", "no file content ever returned, only errors", "3 encodings all blocked"]
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"class": "xxe",
|
|
99
|
+
"name": "XML External Entity",
|
|
100
|
+
"cwe": "CWE-611",
|
|
101
|
+
"keywords": ["xxe", "xml", "external entity", "doctype", "dtd"],
|
|
102
|
+
"negative_keywords": ["external entities disabled", "secure processing", "docx only", "no xml"],
|
|
103
|
+
"proof_oracle": "oob",
|
|
104
|
+
"test_vectors": ["<!DOCTYPE x [<!ENTITY e SYSTEM \"http://callback/\">]><x>&e;</x>", "<!ENTITY e SYSTEM \"file:///etc/passwd\">"],
|
|
105
|
+
"negative_control": "an XML without the entity must NOT fire the callback",
|
|
106
|
+
"followup": ["read local files (file://)", "SSRF via external entity", "exfiltrate via OOB parameter entity"],
|
|
107
|
+
"chain_with": ["data_exposure", "ssrf"],
|
|
108
|
+
"kill_conditions": ["entity not expanded (no callback, no file content)", "parser rejects DOCTYPE", "input is not XML"]
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"class": "deserialization",
|
|
112
|
+
"name": "Insecure Deserialization",
|
|
113
|
+
"cwe": "CWE-502",
|
|
114
|
+
"keywords": ["deserialization", "unserialize", "pickle", "java object", "json.net", "gadget", "ysoserial"],
|
|
115
|
+
"negative_keywords": ["safe type allowlist", "serialization binder", "no user input to deserialize"],
|
|
116
|
+
"proof_oracle": "timing",
|
|
117
|
+
"test_vectors": ["ysoserial gadget chain", "pickle RCE payload", "PHP pop chain", "python cPickle __reduce__"],
|
|
118
|
+
"negative_control": "a benign serialized object must deserialize without side effect",
|
|
119
|
+
"followup": ["identify gadget chain", "trigger via crafted object", "confirm code exec, not just a type error"],
|
|
120
|
+
"chain_with": ["rce"],
|
|
121
|
+
"kill_conditions": ["no gadget chain available for the framework", "input is deserialized with a strict type allowlist", "deserialization is not reachable from user input"]
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"class": "csrf",
|
|
125
|
+
"name": "Cross-Site Request Forgery",
|
|
126
|
+
"cwe": "CWE-352",
|
|
127
|
+
"keywords": ["csrf", "cross-site request forgery", "missing token", "no csrf"],
|
|
128
|
+
"negative_keywords": ["csrf token", "samesite=strict", "origin checked", "double submit"],
|
|
129
|
+
"proof_oracle": "differential",
|
|
130
|
+
"test_vectors": ["replay state-changing request without CSRF token", "cross-origin form", "JSON with CORS misconfig"],
|
|
131
|
+
"negative_control": "a request WITH the token succeeds; WITHOUT must fail",
|
|
132
|
+
"followup": ["confirm a state change (not just a 200)", "chain with CORS to read responses"],
|
|
133
|
+
"chain_with": ["account_takeover", "priv_esc"],
|
|
134
|
+
"kill_conditions": ["token is validated and not guessable", "SameSite=Strict + origin check", "no state-changing action without token"]
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"class": "jwt",
|
|
138
|
+
"name": "JWT / Auth Token Attacks",
|
|
139
|
+
"cwe": "CWE-287",
|
|
140
|
+
"keywords": ["jwt", "json web token", "alg none", "token", "bearer"],
|
|
141
|
+
"negative_keywords": ["signature verified", "rs256 enforced", "key rotation"],
|
|
142
|
+
"proof_oracle": "differential",
|
|
143
|
+
"test_vectors": ["alg:none with empty signature", "alg:HS256 with public key", "kid path traversal", "expired token replay"],
|
|
144
|
+
"negative_control": "a tampered token must be rejected with 401",
|
|
145
|
+
"followup": ["forge admin token", "confused-deputy key swap", "test kid/jku injection"],
|
|
146
|
+
"chain_with": ["auth_bypass", "priv_esc", "account_takeover"],
|
|
147
|
+
"kill_conditions": ["signature strictly verified + alg pinned", "tampered token consistently 401", "no kid/jku/alg confusion surface"]
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"class": "open_redirect",
|
|
151
|
+
"name": "Open Redirect",
|
|
152
|
+
"cwe": "CWE-601",
|
|
153
|
+
"keywords": ["open redirect", "redirect", "return url", "next param", "location header"],
|
|
154
|
+
"negative_keywords": ["whitelist", "allowlist", "relative only", "same host"],
|
|
155
|
+
"proof_oracle": "differential",
|
|
156
|
+
"test_vectors": ["?url=https://evil.com", "?next=//evil.com", "?return=javascript:alert(1)"],
|
|
157
|
+
"negative_control": "a same-host URL redirects, an external URL must not",
|
|
158
|
+
"followup": ["confirm external redirect fires", "chain into OAuth/token theft", "escalate to SSRF if server follows"],
|
|
159
|
+
"chain_with": ["account_takeover", "phishing"],
|
|
160
|
+
"kill_conditions": ["only relative/same-host redirects allowed", "strict allowlist", "redirect target validated server-side"]
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"class": "auth_bypass",
|
|
164
|
+
"name": "Authentication Bypass",
|
|
165
|
+
"cwe": "CWE-287",
|
|
166
|
+
"keywords": ["auth bypass", "authentication bypass", "login bypass", "forced browsing"],
|
|
167
|
+
"negative_keywords": ["mfa", "session validated", "auth middleware"],
|
|
168
|
+
"proof_oracle": "differential",
|
|
169
|
+
"test_vectors": ["forced browsing to protected endpoint", "role/type confusion", "empty/invalid session", "default creds"],
|
|
170
|
+
"negative_control": "unauthenticated access must return 401/403/redirect to login",
|
|
171
|
+
"followup": ["confirm protected resource served without auth", "default credentials", "race the auth check"],
|
|
172
|
+
"chain_with": ["data_exposure", "priv_esc", "account_takeover"],
|
|
173
|
+
"kill_conditions": ["every protected route enforces auth", "no default/blank creds", "session is server-validated"]
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"class": "proto_pollution",
|
|
177
|
+
"name": "Prototype Pollution",
|
|
178
|
+
"cwe": "CWE-1321",
|
|
179
|
+
"keywords": ["prototype pollution", "__proto__", "constructor.prototype", "object merge"],
|
|
180
|
+
"negative_keywords": ["object freeze", "json.parse only", "no merge"],
|
|
181
|
+
"proof_oracle": "differential",
|
|
182
|
+
"test_vectors": ["__proto__[isAdmin]=true", "constructor.prototype.x=1", "?__proto__.x=1"],
|
|
183
|
+
"negative_control": "a clean object must not gain polluted properties",
|
|
184
|
+
"followup": ["confirm polluted property affects control flow", "chain to RCE/XSS/auth bypass"],
|
|
185
|
+
"chain_with": ["rce", "auth_bypass", "xss"],
|
|
186
|
+
"kill_conditions": ["no unsafe merge/deep-merge", "Object.freeze / null-prototype used", "pollution has no observable effect"]
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"class": "nosql",
|
|
190
|
+
"name": "NoSQL Injection",
|
|
191
|
+
"cwe": "CWE-943",
|
|
192
|
+
"keywords": ["nosql", "mongodb", "mongo", "operator injection", "$ne", "$gt"],
|
|
193
|
+
"negative_keywords": ["orm", "schema validated", "relational"],
|
|
194
|
+
"proof_oracle": "differential",
|
|
195
|
+
"test_vectors": ["{\"$ne\": null}", "{\"$gt\": \"\"}", "password[$ne]=x", "{\"$where\": \"sleep(5000)\"}"],
|
|
196
|
+
"negative_control": "a literal string must not be interpreted as an operator",
|
|
197
|
+
"followup": ["bypass auth with $ne/$gt", "extract via $regex", "time-based $where"],
|
|
198
|
+
"chain_with": ["auth_bypass", "data_exposure", "rce"],
|
|
199
|
+
"kill_conditions": ["input is a plain string not parsed as object", "operators escaped/sanitized", "schema validation rejects operator keys"]
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"class": "crlf",
|
|
203
|
+
"name": "CRLF Injection / Header Injection",
|
|
204
|
+
"cwe": "CWE-93",
|
|
205
|
+
"keywords": ["crlf", "header injection", "log injection", "response splitting", "%0d%0a"],
|
|
206
|
+
"negative_keywords": ["header sanitized", "urlencoded", "blocked newline"],
|
|
207
|
+
"proof_oracle": "differential",
|
|
208
|
+
"test_vectors": ["%0d%0aSet-Cookie: evil=1", "%0d%0aX-Injected: 1", "\r\nLocation: http://evil.com"],
|
|
209
|
+
"negative_control": "a value without CRLF must not inject a header",
|
|
210
|
+
"followup": ["inject a header (set-cookie/location)", "log forging", "response splitting"],
|
|
211
|
+
"chain_with": ["xss", "open_redirect", "session_fixation"],
|
|
212
|
+
"kill_conditions": ["CR/LF stripped or encoded in the reflected position", "no user input reaches headers/logs", "framework blocks newline"]
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"class": "file_upload",
|
|
216
|
+
"name": "Arbitrary File Upload",
|
|
217
|
+
"cwe": "CWE-434",
|
|
218
|
+
"keywords": ["file upload", "upload", "multipart", "avatar", "attachment"],
|
|
219
|
+
"negative_keywords": ["extension allowlist", "content validated", "mime checked", "execution denied"],
|
|
220
|
+
"proof_oracle": "differential",
|
|
221
|
+
"test_vectors": ["shell.php", "shell.php.jpg", "shell.pHp", "shell.php%00.jpg", ".htaccess", "svg with script"],
|
|
222
|
+
"negative_control": "a benign image must upload but a .php must be rejected OR stored non-executable",
|
|
223
|
+
"followup": ["reach the uploaded file", "confirm execution (not just storage)", "double-extension/encoding bypass"],
|
|
224
|
+
"chain_with": ["rce"],
|
|
225
|
+
"kill_conditions": [".php rejected or stored with no execute path", "content+MIME+extension all validated", "uploaded dir is non-executable / renamed"]
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blitzstrike",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.191",
|
|
4
4
|
"description": "Blitz Strike — a universal MCP security-audit toolbelt. BLITZ sweeps the attack surface, EAGLE-EYE traces source-to-sink, STRIKE verifies live. 57 attack chains, 130-tool catalog, intelligence data layer. One server, every agent.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|