blitzstrike 2.4.95 → 2.4.96
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 +15 -0
- package/dist/index.js +14 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,21 @@ 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.96] — 2026-09-17
|
|
9
|
+
|
|
10
|
+
### Security — self-audit (command injection + path traversal fixed)
|
|
11
|
+
|
|
12
|
+
- `resolve_check(host)` interpolated the user-controlled host into a `curl` shell
|
|
13
|
+
string (`execSync`), allowing command injection (`host = "x.com; id"`). Now
|
|
14
|
+
validates the host against a strict hostname regex BEFORE any subprocess/DNS and
|
|
15
|
+
calls curl via `execFileSync` (array argv, no shell) — defense in depth.
|
|
16
|
+
- `foundry_run(contract_name=...)` used the name as a filename under the temp
|
|
17
|
+
project without validation, allowing path traversal (`"../../evil"`). Now
|
|
18
|
+
sanitizes to a valid Solidity identifier (`[A-Za-z_][A-Za-z0-9_]*`), defaulting
|
|
19
|
+
to `Vulnerable` otherwise.
|
|
20
|
+
- Added regression checks: `isValidHostname` rejects shell metacharacters
|
|
21
|
+
(`;`, backticks, `$()`, `|`, `../`, newlines); the identifier regex is shared.
|
|
22
|
+
|
|
8
23
|
## [2.4.95] — 2026-09-17
|
|
9
24
|
|
|
10
25
|
### Fixed — full interconnection audit (unreachable template + 2 ungrounded classes)
|
package/dist/index.js
CHANGED
|
@@ -17499,7 +17499,7 @@ var init_update = __esm(() => {
|
|
|
17499
17499
|
import { readFileSync as readFileSync29, existsSync as existsSync16 } from "node:fs";
|
|
17500
17500
|
import { join as join27 } from "node:path";
|
|
17501
17501
|
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
17502
|
-
import { execSync as
|
|
17502
|
+
import { execSync as execSync4 } from "node:child_process";
|
|
17503
17503
|
function validateRelease() {
|
|
17504
17504
|
const checks = [];
|
|
17505
17505
|
checks.push({ name: "package.json version", ok: true, detail: VERSION });
|
|
@@ -17516,13 +17516,13 @@ function validateRelease() {
|
|
|
17516
17516
|
checks.push({ name: "CHANGELOG version", ok: false, detail: "CHANGELOG.md not found" });
|
|
17517
17517
|
}
|
|
17518
17518
|
try {
|
|
17519
|
-
const tag =
|
|
17519
|
+
const tag = execSync4("git describe --tags --abbrev=0", { cwd: ROOT8, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
17520
17520
|
checks.push({ name: "Git tag", ok: tag === `v${VERSION}`, detail: tag, soft: true });
|
|
17521
17521
|
} catch {
|
|
17522
17522
|
checks.push({ name: "Git tag", ok: true, detail: "unavailable (no git/tags)", soft: true });
|
|
17523
17523
|
}
|
|
17524
17524
|
try {
|
|
17525
|
-
const published =
|
|
17525
|
+
const published = execSync4("npm view blitzstrike version", { encoding: "utf8", timeout: 8000, stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
17526
17526
|
checks.push({ name: "npm registry version", ok: published === VERSION, detail: published, soft: true });
|
|
17527
17527
|
} catch {
|
|
17528
17528
|
checks.push({ name: "npm registry version", ok: true, detail: "unavailable (offline)", soft: true });
|
|
@@ -61408,7 +61408,8 @@ function parseTestResults(out) {
|
|
|
61408
61408
|
}
|
|
61409
61409
|
async function foundryRun(input) {
|
|
61410
61410
|
const forge = findForge();
|
|
61411
|
-
const
|
|
61411
|
+
const rawName = input.contract_name ?? "Vulnerable";
|
|
61412
|
+
const name = /^[A-Za-z_][A-Za-z0-9_]{0,63}$/.test(rawName) ? rawName : "Vulnerable";
|
|
61412
61413
|
if (!forge) {
|
|
61413
61414
|
return {
|
|
61414
61415
|
forge: null,
|
|
@@ -61459,11 +61460,15 @@ solc = "0.8.20"
|
|
|
61459
61460
|
}
|
|
61460
61461
|
|
|
61461
61462
|
// src/hunting-intel.ts
|
|
61462
|
-
import {
|
|
61463
|
+
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
61463
61464
|
import { resolve4 as resolve42, Resolver } from "node:dns/promises";
|
|
61464
61465
|
import { readFileSync as readFileSync25 } from "node:fs";
|
|
61465
61466
|
import { join as join24 } from "node:path";
|
|
61466
61467
|
var BLOCKING_KEYWORDS = /internet positif|kominfo|\.go\.id\b|pemblokiran|ditutup|dilarang|akses dibatasi|blocked|restricted|illegal|advertencia|coljuegos|regulat|forbidden|this (site|website) has been (blocked|banned)/i;
|
|
61468
|
+
var HOSTNAME_RE = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i;
|
|
61469
|
+
function isValidHostname(host) {
|
|
61470
|
+
return host.length <= 253 && HOSTNAME_RE.test(host);
|
|
61471
|
+
}
|
|
61467
61472
|
async function localResolve(host) {
|
|
61468
61473
|
try {
|
|
61469
61474
|
return await resolve42(host);
|
|
@@ -61484,7 +61489,7 @@ function probeBlockingPage(host, ip, timeoutMs = 8000) {
|
|
|
61484
61489
|
for (const port of ["443", "80"]) {
|
|
61485
61490
|
const scheme = port === "443" ? "https" : "http";
|
|
61486
61491
|
try {
|
|
61487
|
-
const out =
|
|
61492
|
+
const out = execFileSync5("curl", ["-sk", "-m", "6", "--resolve", `${host}:${port}:${ip}`, `${scheme}://${host}/`], { encoding: "utf8", timeout: timeoutMs, stdio: ["ignore", "pipe", "ignore"] });
|
|
61488
61493
|
const preview = out.replace(/\s+/g, " ").trim().slice(0, 300);
|
|
61489
61494
|
if (!preview)
|
|
61490
61495
|
continue;
|
|
@@ -61495,6 +61500,9 @@ function probeBlockingPage(host, ip, timeoutMs = 8000) {
|
|
|
61495
61500
|
}
|
|
61496
61501
|
async function resolveCheck(host) {
|
|
61497
61502
|
const clean = host.replace(/^https?:\/\//, "").split("/")[0];
|
|
61503
|
+
if (!isValidHostname(clean)) {
|
|
61504
|
+
return { host: clean, local_ips: [], public_ips: [], sinkhole: false, verdict: "invalid", evidence: "not a valid hostname — rejected before DNS/subprocess" };
|
|
61505
|
+
}
|
|
61498
61506
|
const local = await localResolve(clean);
|
|
61499
61507
|
const pub = await publicResolve(clean);
|
|
61500
61508
|
if (local.length === 0 && pub.length === 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blitzstrike",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.96",
|
|
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": {
|