blitzstrike 2.4.61 → 2.4.63
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 +29 -0
- package/dist/index.js +251 -128
- package/intelligence/patterns.json +62 -22
- package/intelligence/variants.json +352 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "blitzstrike-patterns-v1",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"_comment": "Empirical grounding layer. Every detector type is traced to its real-world bug class (CWE), its real-world signature, the chains it composes into (cross-ref chains.json), and
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"_comment": "Empirical grounding layer. Every detector type is traced to its real-world bug class (CWE), its real-world signature, the chains it composes into (cross-ref chains.json), citable references, per-class bypass techniques, and the high-value assets (crown jewels) that class typically hits. Detection is derived from this data, never hardcoded. References are public standards (CWE/OWASP) and disclosed-report classes — no vendor/product framing.",
|
|
5
5
|
"patterns": [
|
|
6
6
|
{
|
|
7
7
|
"id": "sql_injection",
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
"real_world": "User input is interpolated into a SQL query by string concatenation instead of parameterization. The single most-reported web class; real disclosures range from boolean/UNION extraction to stacked queries for admin takeover.",
|
|
11
11
|
"detection_signatures": ["raw string-interpolated query into a SQL sink", "no prepare()/parameterization", "cross-file: concatenated variable with no visible source"],
|
|
12
12
|
"chain_templates": ["sqli_to_rce", "sqli_to_hash_dump_and_crack", "sql_injection_to_rce", "second_order_sqli"],
|
|
13
|
-
"references": ["CWE-89", "OWASP A03:2021 Injection"]
|
|
13
|
+
"references": ["CWE-89", "OWASP A03:2021 Injection"],
|
|
14
|
+
"bypass_techniques": ["comment/whitespace obfuscation to slip past keyword filters", "hex + double-URL encoding of payloads", "second-order: store payload, trigger on a later read", "time-based blind when output is suppressed", "chunked/case-mangled keywords"],
|
|
15
|
+
"crown_jewels": ["credential + session tables", "admin/role tables", "PII and financial records", "password-hash dumps for offline cracking"]
|
|
14
16
|
},
|
|
15
17
|
{
|
|
16
18
|
"id": "ssrf",
|
|
@@ -19,7 +21,9 @@
|
|
|
19
21
|
"real_world": "A server fetches an attacker-supplied URL with no host allowlist, letting it reach cloud metadata endpoints, internal services, or the loopback interface.",
|
|
20
22
|
"detection_signatures": ["server-side fetch of a request-controlled URL", "no host/allowlist validation"],
|
|
21
23
|
"chain_templates": ["ssrf_cloud_metadata", "ssrf_to_redis_rce", "blind_ssrf_to_oob_exfil"],
|
|
22
|
-
"references": ["CWE-918", "OWASP A10:2021 SSRF"]
|
|
24
|
+
"references": ["CWE-918", "OWASP A10:2021 SSRF"],
|
|
25
|
+
"bypass_techniques": ["DNS rebinding to pass host checks", "decimal/octal/hex + IPv6 IP encodings", "redirect chains to a blocklisted host", "gopher/dict/file URL schemes", "localhost aliases (0, 127.1, ::1)"],
|
|
26
|
+
"crown_jewels": ["cloud metadata (169.254.169.254) for instance credentials", "internal admin panels + APIs", "internal Redis/DB/Elasticsearch", "cloud IAM / STS AssumeRole endpoints"]
|
|
23
27
|
},
|
|
24
28
|
{
|
|
25
29
|
"id": "ssti",
|
|
@@ -28,7 +32,9 @@
|
|
|
28
32
|
"real_world": "User input reaches a template engine (Jinja2, Twig, Freemarker, ERB, …) that evaluates expressions, yielding code execution via template syntax like {{7*7}}.",
|
|
29
33
|
"detection_signatures": ["template render of request input", "expression evaluation in a template engine"],
|
|
30
34
|
"chain_templates": ["ssti_template_injection_rce", "ssti_to_full_rce"],
|
|
31
|
-
"references": ["CWE-1336", "OWASP A03:2021 Injection"]
|
|
35
|
+
"references": ["CWE-1336", "OWASP A03:2021 Injection"],
|
|
36
|
+
"bypass_techniques": ["sandbox escape via attribute/object introspection", "unicode/alternate delimiter to dodge input filters", "chaining globals/locals to reach builtins", "engine-specific escapes (Jinja2 → Python, Twig → PHP)"],
|
|
37
|
+
"crown_jewels": ["direct RCE", "config files + secrets", "template/partials with injected backdoors"]
|
|
32
38
|
},
|
|
33
39
|
{
|
|
34
40
|
"id": "xxe",
|
|
@@ -37,7 +43,9 @@
|
|
|
37
43
|
"real_world": "An XML parser resolves external entities, letting an attacker read local files or hit internal URLs via DOCTYPE entity definitions.",
|
|
38
44
|
"detection_signatures": ["XML parse without disabling external entities", "DOCTYPE/ENTITY processing"],
|
|
39
45
|
"chain_templates": ["xxe_to_ssrf_and_file_read"],
|
|
40
|
-
"references": ["CWE-611", "OWASP A03:2021 Injection"]
|
|
46
|
+
"references": ["CWE-611", "OWASP A03:2021 Injection"],
|
|
47
|
+
"bypass_techniques": ["parameter entities + external DTD for blind exfiltration", "OOB (out-of-band) via FTP/HTTP entity callbacks", "UTF-7/UTF-16 encodings to dodge ASCII filters", "XInclude when DOCTYPE is blocked"],
|
|
48
|
+
"crown_jewels": ["local files (/etc/passwd, app keys, .env)", "internal SSRF via entity", "cloud metadata via file:// + SSRF chain"]
|
|
41
49
|
},
|
|
42
50
|
{
|
|
43
51
|
"id": "deserialization",
|
|
@@ -46,7 +54,9 @@
|
|
|
46
54
|
"real_world": "Attacker-controlled serialized data is deserialized and escalated through a magic-method gadget chain (__destruct/__wakeup/__toString) into code execution or object injection.",
|
|
47
55
|
"detection_signatures": ["unserialize()/pickle.loads/yaml.load of request data", "a magic-method gadget in scope"],
|
|
48
56
|
"chain_templates": ["deserialization_pop_chain", "deserialization_to_rce", "appkey_leak_deserialization_rce"],
|
|
49
|
-
"references": ["CWE-502", "OWASP A08:2021 Software and Data Integrity Failures"]
|
|
57
|
+
"references": ["CWE-502", "OWASP A08:2021 Software and Data Integrity Failures"],
|
|
58
|
+
"bypass_techniques": ["custom gadget chains for the app's own classes", "phar:// stream wrappers to trigger unserialize", "wrapper formats (pickle, yaml, jsonpickle)", "encrypted-session forgery once a secret leaks"],
|
|
59
|
+
"crown_jewels": ["RCE via gadget chain", "session/cookie forgery", "admin object injection"]
|
|
50
60
|
},
|
|
51
61
|
{
|
|
52
62
|
"id": "type_juggling",
|
|
@@ -55,7 +65,9 @@
|
|
|
55
65
|
"real_world": "A loose comparison (==) between user input and a hash/secret collapses via the 0e magic-hash or numeric-string coercion, bypassing authentication.",
|
|
56
66
|
"detection_signatures": ["loose comparison == of user input against a secret/hash", "0e-prefixed or numeric-string coercion"],
|
|
57
67
|
"chain_templates": ["php_type_juggling_auth_bypass"],
|
|
58
|
-
"references": ["CWE-697", "OWASP A07:2021 Identification and Authentication Failures"]
|
|
68
|
+
"references": ["CWE-697", "OWASP A07:2021 Identification and Authentication Failures"],
|
|
69
|
+
"bypass_techniques": ["0e magic hashes (0e1234… == 0e5678…)", "numeric-string coercion (\"1admin\" == 1)", "array comparison (array() == false)", "null/empty-string coercion"],
|
|
70
|
+
"crown_jewels": ["authentication bypass", "session/cookie validation bypass", "API token check bypass"]
|
|
59
71
|
},
|
|
60
72
|
{
|
|
61
73
|
"id": "mass_assignment",
|
|
@@ -64,7 +76,9 @@
|
|
|
64
76
|
"real_world": "Request data is bound to model fields without an allowlist (extract()/parse_str/framework mass-assign), letting an attacker set privileged fields like role or is_admin.",
|
|
65
77
|
"detection_signatures": ["extract()/parse_str of request data without a safe flag", "model binding without an allowlist"],
|
|
66
78
|
"chain_templates": ["mass_assignment_to_admin_takeover", "extract_variable_injection_lfi"],
|
|
67
|
-
"references": ["CWE-915", "OWASP API6:2023 Unrestricted Access to Sensitive Business Flows"]
|
|
79
|
+
"references": ["CWE-915", "OWASP API6:2023 Unrestricted Access to Sensitive Business Flows"],
|
|
80
|
+
"bypass_techniques": ["nested/array parameters to reach guarded fields", "JSON body field injection", "adding is_admin/role/verified fields to a request", "framework default mass-assign without allowlist"],
|
|
81
|
+
"crown_jewels": ["role / is_admin / is_verified flags", "subscription tier + pricing fields", "account ownership / org membership"]
|
|
68
82
|
},
|
|
69
83
|
{
|
|
70
84
|
"id": "prototype_pollution",
|
|
@@ -73,7 +87,9 @@
|
|
|
73
87
|
"real_world": "A deep merge of request data into an object pollutes Object.prototype, corrupting logic and escalating to code execution in gadget-heavy runtimes.",
|
|
74
88
|
"detection_signatures": ["deep merge/extend of request data into objects", "__proto__ / constructor.prototype assignment"],
|
|
75
89
|
"chain_templates": ["prototype_pollution_to_rce"],
|
|
76
|
-
"references": ["CWE-1321"]
|
|
90
|
+
"references": ["CWE-1321"],
|
|
91
|
+
"bypass_techniques": ["__proto__ via constructor.prototype aliases", "array-key pollution to reach the merge", "gadget chaining to RCE", "property injection to bypass auth/ACL"],
|
|
92
|
+
"crown_jewels": ["RCE gadgets (child_process, template engines)", "authentication/ACL bypass", "XSS or property-injection escalation"]
|
|
77
93
|
},
|
|
78
94
|
{
|
|
79
95
|
"id": "crlf_injection",
|
|
@@ -82,7 +98,9 @@
|
|
|
82
98
|
"real_world": "Request-controlled newlines are written into an HTTP header, enabling response splitting, cookie injection, or cache poisoning.",
|
|
83
99
|
"detection_signatures": ["request input reaches a header without CR/LF stripping"],
|
|
84
100
|
"chain_templates": ["cache_poisoning_xss", "cache_poison_to_stored_xss"],
|
|
85
|
-
"references": ["CWE-93", "OWASP A03:2021 Injection"]
|
|
101
|
+
"references": ["CWE-93", "OWASP A03:2021 Injection"],
|
|
102
|
+
"bypass_techniques": ["double-URL-encoded %0d%0a", "unicode line separators (U+2028/U+2029)", "header smuggling via folded headers"],
|
|
103
|
+
"crown_jewels": ["Set-Cookie injection → session fixation", "response splitting → XSS", "cache poisoning → stored XSS"]
|
|
86
104
|
},
|
|
87
105
|
{
|
|
88
106
|
"id": "path_confusion",
|
|
@@ -91,7 +109,9 @@
|
|
|
91
109
|
"real_world": "A request-controlled path is normalized or resolved without confinement (../, %2e%2e, absolute paths), reading or writing files outside the intended directory.",
|
|
92
110
|
"detection_signatures": ["request input reaches a file path without confinement"],
|
|
93
111
|
"chain_templates": ["path_traversal_file_write", "path_traversal_to_credential_theft", "lfi_log_poison_rce", "lfi_to_rce_via_log_poisoning"],
|
|
94
|
-
"references": ["CWE-22", "OWASP A01:2021 Broken Access Control"]
|
|
112
|
+
"references": ["CWE-22", "OWASP A01:2021 Broken Access Control"],
|
|
113
|
+
"bypass_techniques": ["null-byte truncation (legacy PHP)", "double encoding %252e%252e%252f", "unicode + absolute-path variants", "symlink / wildcard resolution", "log-poisoning to turn LFI into RCE"],
|
|
114
|
+
"crown_jewels": ["config files + .env + private keys", "/etc/passwd and shadow", "source code for further audit", "writable dirs for a shell drop"]
|
|
95
115
|
},
|
|
96
116
|
{
|
|
97
117
|
"id": "wrong_sanitizer",
|
|
@@ -100,7 +120,9 @@
|
|
|
100
120
|
"real_world": "A value is sanitized for one context (e.g. HTML) but reaches a sink that needs a different context (e.g. SQL), so the sanitizer provides no real protection.",
|
|
101
121
|
"detection_signatures": ["a sanitizer/validator for context X feeding a sink that requires context Y"],
|
|
102
122
|
"chain_templates": ["second_order_sqli"],
|
|
103
|
-
"references": ["CWE-20", "OWASP A03:2021 Injection"]
|
|
123
|
+
"references": ["CWE-20", "OWASP A03:2021 Injection"],
|
|
124
|
+
"bypass_techniques": ["context mismatch (HTML-escape then SQL, or vice-versa)", "double encoding to survive a single decode", "sanitizer that misses alternate encodings"],
|
|
125
|
+
"crown_jewels": ["downstream injection (SQLi/XSS/RCE)", "stored data that re-enters a different sink"]
|
|
104
126
|
},
|
|
105
127
|
{
|
|
106
128
|
"id": "missing_authz",
|
|
@@ -109,7 +131,9 @@
|
|
|
109
131
|
"real_world": "A state-changing handler lacks a capability/ownership check, letting an unauthenticated or low-privilege caller perform an admin action.",
|
|
110
132
|
"detection_signatures": ["state-changing operation with no current_user_can/is_user_logged_in check"],
|
|
111
133
|
"chain_templates": ["idor_to_admin_takeover", "mass_assignment_to_admin_takeover", "idor_object_reference"],
|
|
112
|
-
"references": ["CWE-862", "OWASP A01:2021 Broken Access Control"]
|
|
134
|
+
"references": ["CWE-862", "OWASP A01:2021 Broken Access Control"],
|
|
135
|
+
"bypass_techniques": ["HTTP verb tampering (GET vs POST vs PUT)", "sequential/UUID/guessable object-ID enumeration", "cross-tenant / cross-org ID swapping", "header-based authz spoofing"],
|
|
136
|
+
"crown_jewels": ["cross-tenant data + employee PII", "admin/moderator endpoints", "financial documents + billing APIs", "org/account management actions"]
|
|
113
137
|
},
|
|
114
138
|
{
|
|
115
139
|
"id": "missing_nonce",
|
|
@@ -118,7 +142,9 @@
|
|
|
118
142
|
"real_world": "A state-changing action lacks an anti-CSRF token, letting a victim's browser perform the action on their behalf via a forged request.",
|
|
119
143
|
"detection_signatures": ["state-changing operation with no nonce/referer verification"],
|
|
120
144
|
"chain_templates": ["nonce_harvest_auth_bypass"],
|
|
121
|
-
"references": ["CWE-352", "OWASP A01:2021 Broken Access Control"]
|
|
145
|
+
"references": ["CWE-352", "OWASP A01:2021 Broken Access Control"],
|
|
146
|
+
"bypass_techniques": ["empty/null token accepted", "predictable or reusable tokens", "verb switching to skip the check", "referer/Origin header spoofing or absence"],
|
|
147
|
+
"crown_jewels": ["password/email change", "money transfer / payment actions", "admin config changes"]
|
|
122
148
|
},
|
|
123
149
|
{
|
|
124
150
|
"id": "file_upload",
|
|
@@ -127,7 +153,9 @@
|
|
|
127
153
|
"real_world": "A file is uploaded with an attacker-controlled name/extension and no server-side filetype whitelist, landing web-reachable for code execution.",
|
|
128
154
|
"detection_signatures": ["move_uploaded_file/wp_upload_bits with attacker-controlled name", "no extension/mime whitelist", "uploadAllow=all connector config"],
|
|
129
155
|
"chain_templates": ["upload_polyglot_rce", "file_upload_to_rce", "split_controller_upload_bypass"],
|
|
130
|
-
"references": ["CWE-434", "OWASP A04:2021 Insecure Design"]
|
|
156
|
+
"references": ["CWE-434", "OWASP A04:2021 Insecure Design"],
|
|
157
|
+
"bypass_techniques": ["double extension (.php.jpg, .jpg.php)", "null-byte + alternate extensions (.pht, .php5, .phtml)", "content-type/mime spoofing", "polyglot files (valid image + payload)"],
|
|
158
|
+
"crown_jewels": ["web-reachable upload directory", "avatar/profile/document uploads", "document converters (PDF/Office) with a known chain"]
|
|
131
159
|
},
|
|
132
160
|
{
|
|
133
161
|
"id": "priv_esc",
|
|
@@ -136,7 +164,9 @@
|
|
|
136
164
|
"real_world": "A role/capability/user change is fed by request input and reachable from a public entry point with no capability check, letting a user self-assign admin.",
|
|
137
165
|
"detection_signatures": ["set_role/add_role/add_cap of request input", "cross-file: sink reachable from public hook with no capability check"],
|
|
138
166
|
"chain_templates": ["mass_assignment_to_admin_takeover", "idor_to_admin_takeover"],
|
|
139
|
-
"references": ["CWE-269", "OWASP A01:2021 Broken Access Control"]
|
|
167
|
+
"references": ["CWE-269", "OWASP A01:2021 Broken Access Control"],
|
|
168
|
+
"bypass_techniques": ["role parameter injection in registration/profile", "missing capability check on a public hook", "default-role override", "wp_capabilities/user-meta injection"],
|
|
169
|
+
"crown_jewels": ["administrator / superuser role", "tenant-admin role", "org-owner / root capabilities"]
|
|
140
170
|
},
|
|
141
171
|
{
|
|
142
172
|
"id": "hardcoded_secret",
|
|
@@ -145,7 +175,9 @@
|
|
|
145
175
|
"real_world": "A secret (API key, database password, access token, private key) is committed in source, exposing it to anyone with repo access. Real disclosures regularly turn a leaked key into account takeover or cloud compromise.",
|
|
146
176
|
"detection_signatures": ["secret field assigned a literal", "known secret format (JWT/AWS/GitHub/Slack/…) in source", "high-entropy token under a non-obvious name"],
|
|
147
177
|
"chain_templates": ["api_key_leak_to_account_takeover", "appkey_leak_deserialization_rce", "default_creds_to_internal_pivot"],
|
|
148
|
-
"references": ["CWE-798", "OWASP A02:2021 Cryptographic Failures"]
|
|
178
|
+
"references": ["CWE-798", "OWASP A02:2021 Cryptographic Failures"],
|
|
179
|
+
"bypass_techniques": ["base64/hex-encoded secrets that evade naive regex", "secrets split across concatenation", "env-masquerading (default value committed)", "minified/bundled assets hiding keys"],
|
|
180
|
+
"crown_jewels": ["cloud credentials (AWS/GCP/Azure)", "database credentials", "JWT signing keys", "payment/provider API tokens"]
|
|
149
181
|
},
|
|
150
182
|
{
|
|
151
183
|
"id": "llm_injection",
|
|
@@ -154,7 +186,9 @@
|
|
|
154
186
|
"real_world": "Untrusted text reaches an LLM call (chat/completion/invoke) without a prompt-injection boundary, letting the input override instructions, leak the system prompt, or steer the model into a privileged action.",
|
|
155
187
|
"detection_signatures": ["an LLM provider call (openai/anthropic/langchain/llm) with request input in scope", "no visible system-prompt boundary or output filtering"],
|
|
156
188
|
"chain_templates": [],
|
|
157
|
-
"references": ["CWE-77", "OWASP LLM01:2025 Prompt Injection"]
|
|
189
|
+
"references": ["CWE-77", "OWASP LLM01:2025 Prompt Injection"],
|
|
190
|
+
"bypass_techniques": ["delimiter/role confusion to escape the system prompt", "translation/encoding attacks to hide instructions", "context overflow to displace earlier constraints", "indirect injection via fetched documents (RAG)"],
|
|
191
|
+
"crown_jewels": ["the system prompt itself", "tool/function-calling surfaces", "RAG-retrieved data", "privileged actions (email/send/pay) gated on model output"]
|
|
158
192
|
},
|
|
159
193
|
{
|
|
160
194
|
"id": "graphql_exposure",
|
|
@@ -163,7 +197,9 @@
|
|
|
163
197
|
"real_world": "GraphQL introspection or a playground is left enabled in production, exposing the full schema (every query/mutation/field) and enabling interactive querying for recon.",
|
|
164
198
|
"detection_signatures": ["introspection/playground/graphiql set true in a production-reachable config"],
|
|
165
199
|
"chain_templates": ["graphql_idor_to_data_theft", "graphql_batching_to_credential_stuffing"],
|
|
166
|
-
"references": ["CWE-200", "OWASP API2:2023 Broken Authentication"]
|
|
200
|
+
"references": ["CWE-200", "OWASP API2:2023 Broken Authentication"],
|
|
201
|
+
"bypass_techniques": ["alternate introspection queries when the standard one is blocked", "field suggestion / error messages leaking the schema", "aliasing + batching to brute endpoints"],
|
|
202
|
+
"crown_jewels": ["the full schema (every query/mutation/field)", "hidden/admin-only fields", "mutation endpoints for destructive actions"]
|
|
167
203
|
},
|
|
168
204
|
{
|
|
169
205
|
"id": "oauth_misconfig",
|
|
@@ -172,7 +208,9 @@
|
|
|
172
208
|
"real_world": "An OAuth redirect_uri/callback is fed by request input with no static allowlist, letting an attacker redirect the authorization code or token to an attacker-controlled endpoint.",
|
|
173
209
|
"detection_signatures": ["redirect_uri/callback fed by request input", "no allowlist/whitelist validation nearby"],
|
|
174
210
|
"chain_templates": ["oauth_redirect_bypass", "open_redirect_to_oauth_theft"],
|
|
175
|
-
"references": ["CWE-601", "OWASP A07:2021 Identification and Authentication Failures"]
|
|
211
|
+
"references": ["CWE-601", "OWASP A07:2021 Identification and Authentication Failures"],
|
|
212
|
+
"bypass_techniques": ["path/subdomain confusion on the allowlist", "missing or weak state parameter", "authorization-code replay", "OAuth mix-up between IdP and client"],
|
|
213
|
+
"crown_jewels": ["the authorization code", "access/refresh tokens", "account-linking flows"]
|
|
176
214
|
},
|
|
177
215
|
{
|
|
178
216
|
"id": "grpc_reflection",
|
|
@@ -181,7 +219,9 @@
|
|
|
181
219
|
"real_world": "gRPC server reflection is enabled, enumerating every service and method to any caller and leaking the API contract.",
|
|
182
220
|
"detection_signatures": ["enable_server_reflection / RegisterReflectionService in production code"],
|
|
183
221
|
"chain_templates": [],
|
|
184
|
-
"references": ["CWE-200"]
|
|
222
|
+
"references": ["CWE-200"],
|
|
223
|
+
"bypass_techniques": ["grpcurl / reflection API enumeration", "proto extraction to reconstruct the contract", "unauthenticated method invocation once enumerated"],
|
|
224
|
+
"crown_jewels": ["the full API contract (every service/method)", "hidden/internal methods", "input schemas for fuzzing"]
|
|
185
225
|
}
|
|
186
226
|
]
|
|
187
227
|
}
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "blitzstrike-variants-v1",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"_comment": "Variant corpus \u2014 concrete real-world code shapes per detector class. Each variant is a shape that MUST fire its class's detector. The verification harness sweeps every variant and reports per-class coverage, so a detector that misses a shape surfaces as a false negative. Shapes are generic (language-idiomatic), with no vendor/product framing.",
|
|
5
|
+
"variants": [
|
|
6
|
+
{
|
|
7
|
+
"class": "sql_injection",
|
|
8
|
+
"code": "$wpdb->query(\"DELETE FROM t WHERE id=\" . $row['id']);",
|
|
9
|
+
"note": "raw string concat into query"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"class": "sql_injection",
|
|
13
|
+
"code": "$r = $db->query(\"SELECT * FROM users WHERE name='\" . $name . \"'\");",
|
|
14
|
+
"note": "interpolated SELECT"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"class": "sql_injection",
|
|
18
|
+
"code": "mysqli_query($c, \"UPDATE t SET x='\" . $x . \"' WHERE id=\" . $id);",
|
|
19
|
+
"note": "mysqli raw concat"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"class": "sql_injection",
|
|
23
|
+
"code": "knex('users').whereRaw('id = ' + userId)",
|
|
24
|
+
"note": "ORM raw clause"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"class": "ssrf",
|
|
28
|
+
"code": "$ch = curl_init($_GET['url']); curl_exec($ch);",
|
|
29
|
+
"note": "curl to request URL"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"class": "ssrf",
|
|
33
|
+
"code": "$r = file_get_contents($_POST['target']);",
|
|
34
|
+
"note": "file_get_contents request URL"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"class": "ssrf",
|
|
38
|
+
"code": "requests.get(request.args.get('url'))",
|
|
39
|
+
"note": "python requests request URL"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"class": "ssrf",
|
|
43
|
+
"code": "axios.get(req.body.url)",
|
|
44
|
+
"note": "node axios request URL"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"class": "ssti",
|
|
48
|
+
"code": "return jinja2.from_string($_GET['tpl']).render()",
|
|
49
|
+
"note": "jinja from_string request input"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"class": "ssti",
|
|
53
|
+
"code": "$twig->render($_GET['tpl']);",
|
|
54
|
+
"note": "twig render request input"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"class": "ssti",
|
|
58
|
+
"code": "return render_template_string(request.args['tpl'])",
|
|
59
|
+
"note": "flask render_template_string request input"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"class": "ssti",
|
|
63
|
+
"code": "new Template($_GET['template'])",
|
|
64
|
+
"note": "freemarker template request input"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"class": "xxe",
|
|
68
|
+
"code": "$xml = $_POST['xml'];\n$x = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOENT);",
|
|
69
|
+
"note": "simplexml with entity substitution enabled"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"class": "xxe",
|
|
73
|
+
"code": "$xml = $_POST['xml'];\n$x = new SimpleXMLElement($xml, LIBXML_NOENT);",
|
|
74
|
+
"note": "SimpleXMLElement with NOENT"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"class": "xxe",
|
|
78
|
+
"code": "DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(request.getParameter('xml'))",
|
|
79
|
+
"note": "java DOM parse without disabling entities"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"class": "deserialization",
|
|
83
|
+
"code": "$o = unserialize($_COOKIE['data']);\nclass A { function __destruct() { system($this->c); } }",
|
|
84
|
+
"note": "unserialize cookie"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"class": "deserialization",
|
|
88
|
+
"code": "obj = pickle.loads(request.data)",
|
|
89
|
+
"note": "pickle.loads request data"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"class": "deserialization",
|
|
93
|
+
"code": "data = yaml.load(request.data)",
|
|
94
|
+
"note": "unsafe yaml.load"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"class": "deserialization",
|
|
98
|
+
"code": "new ObjectInputStream(request.getInputStream()).readObject()",
|
|
99
|
+
"note": "java readObject"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"class": "type_juggling",
|
|
103
|
+
"code": "if ($_POST['token'] == md5($secret)) { login(); }",
|
|
104
|
+
"note": "loose compare vs md5"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"class": "type_juggling",
|
|
108
|
+
"code": "if ($_GET['pwd'] != $stored_hash) { die('no'); }",
|
|
109
|
+
"note": "loose compare vs hash"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"class": "type_juggling",
|
|
113
|
+
"code": "if (strcmp($_POST['pwd'], $hash) == 0) { login(); }",
|
|
114
|
+
"note": "strcmp array coercion"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"class": "mass_assignment",
|
|
118
|
+
"code": "extract($_REQUEST);",
|
|
119
|
+
"note": "extract request"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"class": "mass_assignment",
|
|
123
|
+
"code": "parse_str(file_get_contents('php://input'), $data);",
|
|
124
|
+
"note": "parse_str raw body"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"class": "mass_assignment",
|
|
128
|
+
"code": "foreach ($_POST as $k => $v) { $this->$k = $v; }",
|
|
129
|
+
"note": "dynamic field binding"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"class": "mass_assignment",
|
|
133
|
+
"code": "User.create(req.body)",
|
|
134
|
+
"note": "model create without allowlist"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"class": "prototype_pollution",
|
|
138
|
+
"code": "_.merge(target, req.body)",
|
|
139
|
+
"note": "lodash merge request body"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"class": "prototype_pollution",
|
|
143
|
+
"code": "Object.assign(obj, req.body)",
|
|
144
|
+
"note": "Object.assign request body"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"class": "prototype_pollution",
|
|
148
|
+
"code": "$.extend(true, {}, req.body)",
|
|
149
|
+
"note": "jquery deep extend request body"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"class": "crlf_injection",
|
|
153
|
+
"code": "header(\"Location: \" . $_GET['url']);",
|
|
154
|
+
"note": "header location request input"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"class": "crlf_injection",
|
|
158
|
+
"code": "setcookie('name', $_GET['v']);",
|
|
159
|
+
"note": "setcookie request value"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"class": "crlf_injection",
|
|
163
|
+
"code": "res.setHeader('Location', req.query.url)",
|
|
164
|
+
"note": "node setHeader request input"
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"class": "path_confusion",
|
|
168
|
+
"code": "include($_GET['page']);",
|
|
169
|
+
"note": "include request path"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"class": "path_confusion",
|
|
173
|
+
"code": "$c = file_get_contents($_GET['file']);",
|
|
174
|
+
"note": "file_get_contents request path"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"class": "path_confusion",
|
|
178
|
+
"code": "readFile(path.join(base, req.query.file))",
|
|
179
|
+
"note": "node readFile joined path"
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"class": "path_confusion",
|
|
183
|
+
"code": "new File(request.getParameter('f'))",
|
|
184
|
+
"note": "java File request param"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"class": "wrong_sanitizer",
|
|
188
|
+
"code": "$x = htmlspecialchars($_GET['q']); $db->query(\"SELECT * FROM t WHERE c='\" . $x . \"'\");",
|
|
189
|
+
"note": "HTML sanitizer into SQL"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"class": "wrong_sanitizer",
|
|
193
|
+
"code": "$x = strip_tags($_GET['q']); mysqli_query($c, \"SELECT * FROM t WHERE c='\" . $x . \"'\");",
|
|
194
|
+
"note": "strip_tags into SQL"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"class": "wrong_sanitizer",
|
|
198
|
+
"code": "$x = esc_html($_GET['q']); $db->query(\"SELECT * FROM t WHERE c='\" . $x . \"'\");",
|
|
199
|
+
"note": "addslashes into SQL"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"class": "missing_authz",
|
|
203
|
+
"code": "add_action('wp_ajax_nopriv_export', 'h'); function h() { update_option('export', $_POST['x']); }",
|
|
204
|
+
"note": "nopriv handler no capability check"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"class": "missing_authz",
|
|
208
|
+
"code": "app.delete('/admin/user/:id', (req, res) => { User.delete(req.params.id); })",
|
|
209
|
+
"note": "admin route no auth"
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"class": "missing_nonce",
|
|
213
|
+
"code": "add_action('wp_ajax_del_order', 'h'); function h() { wp_delete_post((int)$_POST['id']); }",
|
|
214
|
+
"note": "ajax handler state change no nonce"
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"class": "missing_nonce",
|
|
218
|
+
"code": "add_action('wp_ajax_del', 'h'); function h() { wp_delete_post((int)$_POST['id']); }",
|
|
219
|
+
"note": "ajax no nonce check"
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"class": "missing_nonce",
|
|
223
|
+
"code": "add_action('wp_ajax_save', 'h'); function h() { wp_update_post($_POST); }",
|
|
224
|
+
"note": "ajax handler state change no nonce"
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"class": "missing_nonce",
|
|
228
|
+
"code": "add_action('wp_ajax_save', 'h'); function h() { update_option('x', $_POST['x']); }",
|
|
229
|
+
"note": "ajax save no nonce"
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"class": "file_upload",
|
|
233
|
+
"code": "move_uploaded_file($_FILES['f']['tmp_name'], '/uploads/' . $_FILES['f']['name']);",
|
|
234
|
+
"note": "move_uploaded_file raw name"
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"class": "file_upload",
|
|
238
|
+
"code": "wp_upload_bits($_FILES['f']['name'], null, file_get_contents($_FILES['f']['tmp_name']));",
|
|
239
|
+
"note": "wp_upload_bits raw name"
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"class": "file_upload",
|
|
243
|
+
"code": "file.save(path.join(uploadDir, req.files.f.name))",
|
|
244
|
+
"note": "node multer raw name"
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"class": "file_upload",
|
|
248
|
+
"code": "move_uploaded_file($_FILES['f']['tmp_name'], '/uploads/' . basename($_FILES['f']['name']));",
|
|
249
|
+
"note": "basename only, no ext whitelist"
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"class": "priv_esc",
|
|
253
|
+
"code": "$u->set_role($_POST['role']);",
|
|
254
|
+
"note": "set_role request role"
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"class": "priv_esc",
|
|
258
|
+
"code": "update_user_meta($id, 'wp_capabilities', $_POST['caps']);",
|
|
259
|
+
"note": "user meta capabilities request"
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"class": "priv_esc",
|
|
263
|
+
"code": "$u->add_role($_GET['role']);",
|
|
264
|
+
"note": "add_role request role"
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
"class": "priv_esc",
|
|
268
|
+
"code": "db.query(\"UPDATE users SET role='\" + $_POST['role'] + \"' WHERE id=\" + $_POST['id'])",
|
|
269
|
+
"note": "raw role update"
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
"class": "hardcoded_secret",
|
|
273
|
+
"code": "$db_password = \"EXAMPLE_DB_PASSWORD_123\";",
|
|
274
|
+
"note": "db password literal"
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
"class": "hardcoded_secret",
|
|
278
|
+
"code": "const apiKey = \"EXAMPLE_API_KEY_123456789\";",
|
|
279
|
+
"note": "api key literal"
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"class": "hardcoded_secret",
|
|
283
|
+
"code": "$aws_access_key_id = \"EXAMPLE_ACCESS_KEY_123\";",
|
|
284
|
+
"note": "aws key literal"
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
"class": "hardcoded_secret",
|
|
288
|
+
"code": "JWT_SECRET = \"EXAMPLE_JWT_SIGNING_KEY_123\";",
|
|
289
|
+
"note": "jwt secret literal"
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
"class": "llm_injection",
|
|
293
|
+
"code": "openai.chat.completions.create(messages=[{'content': req.body.text}])",
|
|
294
|
+
"note": "openai completion request input"
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
"class": "llm_injection",
|
|
298
|
+
"code": "anthropic.messages.create(prompt=req.body.prompt)",
|
|
299
|
+
"note": "anthropic prompt request input"
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
"class": "llm_injection",
|
|
303
|
+
"code": "llm.invoke(req.body.query)",
|
|
304
|
+
"note": "langchain invoke request input"
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
"class": "graphql_exposure",
|
|
308
|
+
"code": "const server = new ApolloServer({ introspection: true });",
|
|
309
|
+
"note": "apollo introspection on"
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"class": "graphql_exposure",
|
|
313
|
+
"code": "const server = new ApolloServer({ playground: true });",
|
|
314
|
+
"note": "apollo playground on"
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
"class": "graphql_exposure",
|
|
318
|
+
"code": "graphqlHTTP({ schema, graphiql: true })",
|
|
319
|
+
"note": "express-graphql graphiql on"
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
"class": "oauth_misconfig",
|
|
323
|
+
"code": "const redirect_uri = req.query.redirect_uri;",
|
|
324
|
+
"note": "redirect_uri from query"
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
"class": "oauth_misconfig",
|
|
328
|
+
"code": "$redirect_uri = $_GET['redirect_uri'];",
|
|
329
|
+
"note": "redirect_uri from request"
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
"class": "oauth_misconfig",
|
|
333
|
+
"code": "const returnUrl = request.params.get('returnUrl');",
|
|
334
|
+
"note": "returnUrl from request"
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
"class": "grpc_reflection",
|
|
338
|
+
"code": "server.add_service(grpc_reflection_v1alpha.ServerReflectionServicer(...))",
|
|
339
|
+
"note": "grpc reflection servicer"
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
"class": "grpc_reflection",
|
|
343
|
+
"code": "reflection.enable_server_reflection()",
|
|
344
|
+
"note": "reflection enabled"
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
"class": "grpc_reflection",
|
|
348
|
+
"code": "grpc_reflection_v1.ReflectionServicer.to_server(server)",
|
|
349
|
+
"note": "reflection to server"
|
|
350
|
+
}
|
|
351
|
+
]
|
|
352
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blitzstrike",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.63",
|
|
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": {
|