blitzstrike 2.4.53 → 2.4.55
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 +38 -16
- package/dist/index.js +8 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,27 @@ 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.55] — 2026-09-14
|
|
9
|
+
|
|
10
|
+
### Changed — universal framing (no vendor-specific references)
|
|
11
|
+
|
|
12
|
+
- Removed every vendor/plugin-specific name from source comments, test fixtures,
|
|
13
|
+
action-heuristic example data, and the changelog — the tool is framework-agnostic
|
|
14
|
+
and must not embed third-party product names. Detection logic is unchanged; only
|
|
15
|
+
identifiers/examples/comments were generalized.
|
|
16
|
+
|
|
17
|
+
## [2.4.54] — 2026-09-14
|
|
18
|
+
|
|
19
|
+
### Changed — file-upload scope widened + antiscript-not-a-defense regression
|
|
20
|
+
|
|
21
|
+
- Widened the file-upload defense scope from 6 to 30 lines so a nearby
|
|
22
|
+
extension whitelist / wp_check_filetype is still seen.
|
|
23
|
+
- Regression test: an antiscript filename helper (extension-strip) is NOT a
|
|
24
|
+
defense signal — a filename special-char vuln is not extension-based and the
|
|
25
|
+
vulnerable version also calls it; treating antiscript as a defense caused a
|
|
26
|
+
false negative. Remaining file-upload FPs (2/19 clean plugins) are cross-file
|
|
27
|
+
validation or admin-only context — inherent to per-file detection.
|
|
28
|
+
|
|
8
29
|
## [2.4.53] — 2026-09-14
|
|
9
30
|
|
|
10
31
|
### Changed — file-upload precision (FP-reduction from a 19-plugin clean corpus)
|
|
@@ -19,12 +40,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
19
40
|
|
|
20
41
|
## [2.4.52] — 2026-09-14
|
|
21
42
|
|
|
22
|
-
### Added — Unrestricted-upload config detection (
|
|
43
|
+
### Added — Unrestricted-upload config detection (file-manager RCE)
|
|
23
44
|
|
|
24
45
|
- New `detectUnrestrictedUpload`: flags a file-manager/connector config that sets
|
|
25
46
|
`uploadAllow => array('all')` (especially with `uploadOrder => deny,allow`),
|
|
26
|
-
i.e. ANY mimetype — including `.php` — is uploadable. This is the
|
|
27
|
-
connector
|
|
47
|
+
i.e. ANY mimetype — including `.php` — is uploadable. This is the classic
|
|
48
|
+
file-manager connector misconfiguration (CVE-2020-25213); now surfaces
|
|
28
49
|
`file_upload @ connector.minimal.php:157`.
|
|
29
50
|
- System prompt updated so the LLM agent understands AND can try the newest
|
|
30
51
|
detectors: `priv_esc` (role/capability change from request input, cross-file)
|
|
@@ -39,8 +60,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
39
60
|
privileged sink (role/capability/user change) reachable from a public entry
|
|
40
61
|
point with no capability check on the chain. Plus a DIRECT pass that flags a
|
|
41
62
|
role/capability sink whose ARGUMENTS are themselves request input — the
|
|
42
|
-
precise `set_role($id, sanitize_key($_POST['
|
|
43
|
-
|
|
63
|
+
precise `set_role($id, sanitize_key($_POST['role']))` shape (CVE-2023-3460).
|
|
64
|
+
Now surfaces the privilege-escalation sink (was 0).
|
|
44
65
|
|
|
45
66
|
### Changed — precision fixes for role/escalation bugs
|
|
46
67
|
|
|
@@ -59,10 +80,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
59
80
|
|
|
60
81
|
- `iterSourceFiles` previously skipped `lib`/`libraries`/`libs` dirs, which
|
|
61
82
|
silently MISSED entire plugins that keep their own code under `lib/`
|
|
62
|
-
(
|
|
63
|
-
files, now surfacing
|
|
64
|
-
third-party dirs (`third-party`, `third_party`, `vendor`,
|
|
65
|
-
skipped now — a false-negative is worse than any false
|
|
83
|
+
(a migration plugin: 7→150 files scanned; a file-manager plugin's bundled
|
|
84
|
+
library: 17→329 files, now surfacing SQLi + SSRF + path-confusion). Only
|
|
85
|
+
genuinely third-party dirs (`third-party`, `third_party`, `vendor`,
|
|
86
|
+
`node_modules`) are skipped now — a false-negative is worse than any false
|
|
87
|
+
positive.
|
|
66
88
|
|
|
67
89
|
## [2.4.49] — 2026-09-14
|
|
68
90
|
|
|
@@ -89,8 +111,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
89
111
|
the handler actually performs a WRITE (option/meta/user/post/comment writes,
|
|
90
112
|
file upload/write, `$wpdb->query/insert/update/delete`, `wp_mail`, `wp_redirect`).
|
|
91
113
|
Read-only handlers (list/search/get) are no longer flagged — removes the CSRF/
|
|
92
|
-
authz false-positive storm (
|
|
93
|
-
15→1).
|
|
114
|
+
authz false-positive storm (a forms plugin 90→16, a page builder 11→4, a cache
|
|
115
|
+
plugin 15→1).
|
|
94
116
|
- Removed `is_admin()` / `wp_doing_ajax()` from the auth surface — they are
|
|
95
117
|
request-context checks, not authorization (treating them as auth caused false
|
|
96
118
|
negatives).
|
|
@@ -107,8 +129,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
107
129
|
'wp_loaded'|'template_redirect', ...)` that reads request input directly —
|
|
108
130
|
flagged for missing nonce (CSRF) and missing capability (privileged ops).
|
|
109
131
|
- Auth surface widened (`is_admin`, `is_super_admin`, `current_user_can_edit_post`,
|
|
110
|
-
`wp_doing_ajax`). Benchmark:
|
|
111
|
-
authz/nonce findings (class-method handlers now visible).
|
|
132
|
+
`wp_doing_ajax`). Benchmark: a page builder 0→11, a forms plugin ~3→90, an LMS
|
|
133
|
+
plugin 1→11 authz/nonce findings (class-method handlers now visible).
|
|
112
134
|
|
|
113
135
|
## [2.4.46] — 2026-09-14
|
|
114
136
|
|
|
@@ -132,8 +154,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
132
154
|
written file's name/extension is attacker-controlled and no filetype/extension
|
|
133
155
|
validation is present nearby — the classic upload-a-.php-shell → RCE.
|
|
134
156
|
- Benchmark-driven: a blind scan of 10 real vulnerable plugins found this was
|
|
135
|
-
the biggest detection gap (missed in 3 plugins). Now caught in
|
|
136
|
-
contact-form
|
|
157
|
+
the biggest detection gap (missed in 3 plugins). Now caught in a forms plugin
|
|
158
|
+
+ a contact-form plugin; the bundled-library case remains gated by the
|
|
137
159
|
lib/vendor skip policy.
|
|
138
160
|
|
|
139
161
|
## [2.4.44] — 2026-09-14
|
|
@@ -217,7 +239,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
217
239
|
their likely vulnerability class (upload/import→AFU/RCE, delete/write→
|
|
218
240
|
file-write, load/download→LFI, login/reset→auth-bypass, exec/run→command
|
|
219
241
|
injection, settings/update→unauth options change, …) — as DATA, with real
|
|
220
|
-
examples (
|
|
242
|
+
examples (backup_import, slider_upload, backup_download, …).
|
|
221
243
|
- New `action_surface` tool: extract every `wp_ajax_*` action, cross-reference
|
|
222
244
|
the hook (nopriv?) + authz gap (nonce/capability), and return a DERIVED
|
|
223
245
|
priority so the scanner targets the most dangerous action first.
|
package/dist/index.js
CHANGED
|
@@ -56945,9 +56945,9 @@ function detectFileUploadRce(code, file, out) {
|
|
|
56945
56945
|
while ((m = re.exec(code)) !== null) {
|
|
56946
56946
|
const ln = lineNo2(code, m.index);
|
|
56947
56947
|
const l = ls[ln - 1] ?? "";
|
|
56948
|
-
const scope = ls.slice(Math.max(0, ln -
|
|
56948
|
+
const scope = ls.slice(Math.max(0, ln - 30), ln + 3).join(`
|
|
56949
56949
|
`);
|
|
56950
|
-
if (!/\$_FILES\b|tmp_name|getUploadedFile|uploadedFile|\[
|
|
56950
|
+
if (!/\$_FILES\b|tmp_name|getUploadedFile|uploadedFile|\['name'\]/i.test(scope))
|
|
56951
56951
|
continue;
|
|
56952
56952
|
if (/(wp_check_filetype|PATHINFO_EXTENSION|wp_get_mime_types|allowed_?(types|extensions|exts)|mime_?(types|extensions)|in_array\s*\([^)]*\$(?:allowed|whitelist|ext)|wp_handle_upload\s*\(\s*[^)]*test_form\s*=>\s*true)/i.test(scope))
|
|
56953
56953
|
continue;
|
|
@@ -56979,7 +56979,7 @@ function detectUnrestrictedUpload(code, file, out) {
|
|
|
56979
56979
|
category: "Unrestricted upload config (uploadAllow=all)",
|
|
56980
56980
|
severity: denyFirst ? "high" : "medium",
|
|
56981
56981
|
evidence: l.trim(),
|
|
56982
|
-
detail: denyFirst ? "File-manager/connector config sets uploadAllow='all' with uploadOrder deny→allow — every mimetype (including .php) is uploadable → RCE
|
|
56982
|
+
detail: denyFirst ? "File-manager/connector config sets uploadAllow='all' with uploadOrder deny→allow — every mimetype (including .php) is uploadable → RCE." : "File-manager/connector config sets uploadAllow='all' — any file type can be uploaded; verify the upload path is not web-reachable or that a server-side extension whitelist exists."
|
|
56983
56983
|
});
|
|
56984
56984
|
}
|
|
56985
56985
|
}
|
|
@@ -57684,14 +57684,14 @@ function variantScan(root, opts = {}) {
|
|
|
57684
57684
|
|
|
57685
57685
|
// src/action-heuristics.ts
|
|
57686
57686
|
var ACTION_HEURISTICS = [
|
|
57687
|
-
{ pattern: /upload|import|install|activate|plugin|theme/, vuln_class: "Arbitrary File Upload / Plugin Install → RCE", detector: "file_upload + missing_authz", weight: 0.9, examples: ["
|
|
57688
|
-
{ pattern: /write|save|delete|remove|move|rename/, vuln_class: "Arbitrary File Write / Delete / Move", detector: "file_operations", weight: 0.8, examples: ["
|
|
57689
|
-
{ pattern: /load|include|template|file|download|read/, vuln_class: "LFI / Path Traversal / RFI", detector: "path_traversal + file_inclusion", weight: 0.8, examples: ["
|
|
57687
|
+
{ pattern: /upload|import|install|activate|plugin|theme/, vuln_class: "Arbitrary File Upload / Plugin Install → RCE", detector: "file_upload + missing_authz", weight: 0.9, examples: ["backup_import", "demo_upload_import_files", "template_import_install_package", "slider_upload"] },
|
|
57688
|
+
{ pattern: /write|save|delete|remove|move|rename/, vuln_class: "Arbitrary File Write / Delete / Move", detector: "file_operations", weight: 0.8, examples: ["backup_delete"] },
|
|
57689
|
+
{ pattern: /load|include|template|file|download|read/, vuln_class: "LFI / Path Traversal / RFI", detector: "path_traversal + file_inclusion", weight: 0.8, examples: ["backup_download", "get_file", "preview"] },
|
|
57690
57690
|
{ pattern: /exec|run|cmd|shell|eval|code/, vuln_class: "OS Command / Code Injection / eval", detector: "command_execution + code_execution", weight: 0.85, examples: [] },
|
|
57691
57691
|
{ pattern: /import|unserialize|restore|data/, vuln_class: "Insecure Deserialization / Object Injection", detector: "deserialization", weight: 0.8, examples: [] },
|
|
57692
57692
|
{ pattern: /query|search|filter|export|list/, vuln_class: "SQLi → RCE / Create Admin", detector: "sql_execution", weight: 0.7, examples: [] },
|
|
57693
57693
|
{ pattern: /render|shortcode|block|preview/, vuln_class: "SSTI / Shortcode / Block Injection", detector: "ssti", weight: 0.6, examples: [] },
|
|
57694
|
-
{ pattern: /settings|option|update/, vuln_class: "Unauth Options Update / Settings Change / Missing Cap+Nonce", detector: "missing_authz + missing_nonce", weight: 0.85, examples: ["
|
|
57694
|
+
{ pattern: /settings|option|update/, vuln_class: "Unauth Options Update / Settings Change / Missing Cap+Nonce", detector: "missing_authz + missing_nonce", weight: 0.85, examples: ["shop_settings_update", "builder_save"] },
|
|
57695
57695
|
{ pattern: /login|auth|token|reset|verify/, vuln_class: "Auth Bypass / Auto Login / Account Takeover", detector: "missing_authz + type_juggling", weight: 0.9, examples: ["auto-login", "magic link", "reset password"] },
|
|
57696
57696
|
{ pattern: /role|capability|promote|change_role/, vuln_class: "Privilege Escalation", detector: "missing_authz", weight: 0.9, examples: [] },
|
|
57697
57697
|
{ pattern: /register|signup|create_user/, vuln_class: "Register → RCE / AFU / PrivEsc", detector: "file_upload + missing_authz", weight: 0.8, examples: [] }
|
|
@@ -58502,7 +58502,7 @@ function createServer() {
|
|
|
58502
58502
|
` + `- Keep trying every lead AND every chain step until each is verified/executed or blocked, THEN generate_report. Never deliver a bare surface map, and never stop at 'found X' when X enables more.
|
|
58503
58503
|
|
|
58504
58504
|
` + "TWO PATHS:\\n" + "- Source path on disk -> blitz_scan / taint_file / eagle_eye2 (static).\\n" + "- Live URL -> live_recon / active_scan / strike_verify (web-hunting).\\n\\n" + `DEEPEN A FINDING: attack_plan(target, tech, params) to get the prioritized vector plan (decide what to test next with data); list_chains (escalation), chain_links (compose), technique_lookup(cls), payload_lookup, bypass_lookup (blocked). Phase doctrine: read_skill(bs-orchestrate-engagement | bs-web-hunting | bs-source-audit | bs-verify-finding). Campaign plan: read_playbook(target-type). On any failure call retry_guidance(signal) / model_fallback(signal) before giving up.
|
|
58505
|
-
` + "KNOWLEDGE BASE (discover, don't guess): skillLookup(topic) / listSkills for the 40 attack-path + hunting skills (ap-*, hp-*, bs-*); list_attack_vectors / attack_vectors(cat) for the 34-category vector taxonomy; taxonomy(kind) for OWASP/CWE/ASVS/API-top-10; read_playbook(type) for the 17 campaign playbooks; list_manuals / read_tool_manual for 317 tool references; list_tools / run_catalog_tool for the 141-tool catalog. Every tool, skill, and data layer is reachable from these. CROSS-TARGET INTELLIGENCE: strike_resolve auto-records confirmed/false_positive verdicts into the empirical ledger; query it with intelligence(action=hit_rates/top_vectors) so a new target on a known tech inherits historical hit-rates (attack_plan already blends them into success_probability). LIVE PENTEST + TARGETING (black-box, WAF-safe): cache_gap(base_url, endpoint) fuzzes path-normalization + static-extension variants for cache deception/poisoning; blind_oracle(base_url, param, value) detects which SINK a param reaches (sql/ssti/xss) via benign arithmetic (id=1+0, test${7*7}) WITHOUT a malicious payload; param_precedence(base_url, param, A, B) maps duplicate-parameter precedence (first/last-wins) for WAF-bypass. SOURCE TARGETING: action_surface(code) maps every wp_ajax_* action to its vuln class + DERIVED priority (what to look for WHERE); security_state(sanitizers, sink) gives a wrong-context sanitization verdict; framework_knowledge(framework) returns auth/nonce primitives for 9 frameworks; variant_scan(root, signature) mass-sweeps an install base for ONE bug family; patch_analyze(old, new) REVERSES a security patch into the 0-day, and its mine_signature feeds variant_scan to sweep unpatched copies. All of these are DETECTION HINTS — verify each live (strike_verify / browser_validate) before it enters the report. NEWEST DETECTORS — understand AND try them: variant_scan also emits priv_esc (privilege escalation — a role/capability/user change fed by request input, traced cross-file via reverse call-graph, e.g. set_role($id, sanitize_key($_POST['um-role'])) or update_user_meta(...,'wp_capabilities', $_POST[...])) and flags uploadAllow=>array('all') unrestricted-upload configs as file_upload (the
|
|
58505
|
+
` + "KNOWLEDGE BASE (discover, don't guess): skillLookup(topic) / listSkills for the 40 attack-path + hunting skills (ap-*, hp-*, bs-*); list_attack_vectors / attack_vectors(cat) for the 34-category vector taxonomy; taxonomy(kind) for OWASP/CWE/ASVS/API-top-10; read_playbook(type) for the 17 campaign playbooks; list_manuals / read_tool_manual for 317 tool references; list_tools / run_catalog_tool for the 141-tool catalog. Every tool, skill, and data layer is reachable from these. CROSS-TARGET INTELLIGENCE: strike_resolve auto-records confirmed/false_positive verdicts into the empirical ledger; query it with intelligence(action=hit_rates/top_vectors) so a new target on a known tech inherits historical hit-rates (attack_plan already blends them into success_probability). LIVE PENTEST + TARGETING (black-box, WAF-safe): cache_gap(base_url, endpoint) fuzzes path-normalization + static-extension variants for cache deception/poisoning; blind_oracle(base_url, param, value) detects which SINK a param reaches (sql/ssti/xss) via benign arithmetic (id=1+0, test${7*7}) WITHOUT a malicious payload; param_precedence(base_url, param, A, B) maps duplicate-parameter precedence (first/last-wins) for WAF-bypass. SOURCE TARGETING: action_surface(code) maps every wp_ajax_* action to its vuln class + DERIVED priority (what to look for WHERE); security_state(sanitizers, sink) gives a wrong-context sanitization verdict; framework_knowledge(framework) returns auth/nonce primitives for 9 frameworks; variant_scan(root, signature) mass-sweeps an install base for ONE bug family; patch_analyze(old, new) REVERSES a security patch into the 0-day, and its mine_signature feeds variant_scan to sweep unpatched copies. All of these are DETECTION HINTS — verify each live (strike_verify / browser_validate) before it enters the report. NEWEST DETECTORS — understand AND try them: variant_scan also emits priv_esc (privilege escalation — a role/capability/user change fed by request input, traced cross-file via reverse call-graph, e.g. set_role($id, sanitize_key($_POST['um-role'])) or update_user_meta(...,'wp_capabilities', $_POST[...])) and flags uploadAllow=>array('all') unrestricted-upload configs as file_upload (the file-manager/connector shape). TO TRY a priv_esc hit: submit the role field with 'administrator' (or send wp_capabilities meta) and confirm the account actually gains admin. TO TRY an unrestricted-upload hit: POST a .php/.phtml and confirm it lands web-reachable + executes. A static hit is a HYPOTHESIS until verified live — never report unverified.\n" + `PRECISION ANALYSIS — chrome-devtools MCP is MANDATORY, not optional:
|
|
58506
58506
|
` + `- When a lead needs DOM/JS precision — DOM-XSS sink execution, AJAX endpoint + payload interception, JS runtime errors, redirect chains, SSO/token flow, or anything a static HTML glance cannot prove — call drive_devtools(target). It spawns chrome-devtools-mcp and drives a REAL headless browser (navigate -> list_network_requests -> list_console_messages -> evaluate_script), giving reproducible evidence instead of a guess.
|
|
58507
58507
|
` + `- Before calling it, check_mcp() to confirm the browser MCP is available; if not, blitzstrike install-tools or npm i -g chrome-devtools-mcp. Never substitute eyeballing minified JS or a static sink guess when a live browser can PROVE it. This is the precision + consistency layer.
|
|
58508
58508
|
` + "EXTERNAL MCP SERVERS (verified, connect them — NOT one-shot CLIs): chrome-devtools-mcp (29 tools: list_network_requests/get_network_request for raw HTTP interception, list_console_messages for JS errors + DOM-XSS, evaluate_script to run JS, take_screenshot) -> stdio chrome-devtools-mcp --headless --chromeArg=--no-sandbox --chromeArg=--disable-gpu (as root/container this is MANDATORY or the browser crashes; add --proxyServer http://127.0.0.1:8080 to route through Burp, --acceptInsecureCerts for bad TLS). burp-suite-mcp (proxy history + active scan + repeater) -> NOT npm: build the JAR (git clone https://github.com/PortSwigger/mcp-server.git && cd mcp-server && ./gradlew embedProxyJar), load it in Burp Extensions, then connect the client to http://127.0.0.1:9876 (SSE) or the stdio proxy java -jar mcp-proxy-all.jar --sse-url http://127.0.0.1:9876."
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blitzstrike",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.55",
|
|
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": {
|