blitzstrike 2.4.111 → 2.4.113
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 +31 -0
- package/dist/index.js +594 -233
- package/intelligence/cve-corpus.json +37023 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -17110,11 +17110,11 @@ var require_src = __commonJS(function(exports, module) {
|
|
|
17110
17110
|
});
|
|
17111
17111
|
|
|
17112
17112
|
// src/mcp-status.ts
|
|
17113
|
-
import { existsSync as
|
|
17113
|
+
import { existsSync as existsSync11 } from "node:fs";
|
|
17114
17114
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
17115
17115
|
async function checkMcpServers() {
|
|
17116
17116
|
const out = [];
|
|
17117
|
-
const bin = ["/usr/bin/chrome-devtools-mcp", "/usr/local/bin/chrome-devtools-mcp"].find((p) =>
|
|
17117
|
+
const bin = ["/usr/bin/chrome-devtools-mcp", "/usr/local/bin/chrome-devtools-mcp"].find((p) => existsSync11(p));
|
|
17118
17118
|
const npxOk = spawnSync3("npx", ["--version"], { timeout: 8000 }).error === undefined;
|
|
17119
17119
|
const devtoolsOk = Boolean(bin) || npxOk;
|
|
17120
17120
|
out.push({
|
|
@@ -17388,12 +17388,12 @@ document.getElementById('out').innerHTML = u;
|
|
|
17388
17388
|
});
|
|
17389
17389
|
|
|
17390
17390
|
// src/variants.ts
|
|
17391
|
-
import { readFileSync as
|
|
17392
|
-
import { join as
|
|
17393
|
-
import { fileURLToPath as
|
|
17391
|
+
import { readFileSync as readFileSync24 } from "node:fs";
|
|
17392
|
+
import { join as join23, dirname as dirname5 } from "node:path";
|
|
17393
|
+
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
17394
17394
|
function loadVariants() {
|
|
17395
17395
|
try {
|
|
17396
|
-
const doc = JSON.parse(
|
|
17396
|
+
const doc = JSON.parse(readFileSync24(join23(__dirname5, "..", "intelligence", "variants.json"), "utf8"));
|
|
17397
17397
|
return doc.variants ?? [];
|
|
17398
17398
|
} catch {
|
|
17399
17399
|
return [];
|
|
@@ -17447,19 +17447,19 @@ function variantCoverageText() {
|
|
|
17447
17447
|
var __dirname5, CROSS_FILE_ONLY;
|
|
17448
17448
|
var init_variants = __esm(() => {
|
|
17449
17449
|
init_complex_bugs();
|
|
17450
|
-
__dirname5 = dirname5(
|
|
17450
|
+
__dirname5 = dirname5(fileURLToPath14(import.meta.url));
|
|
17451
17451
|
CROSS_FILE_ONLY = new Set(["priv_esc"]);
|
|
17452
17452
|
});
|
|
17453
17453
|
|
|
17454
17454
|
// src/sync.ts
|
|
17455
|
-
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync9, readFileSync as
|
|
17456
|
-
import { join as
|
|
17457
|
-
import { homedir as
|
|
17458
|
-
import { fileURLToPath as
|
|
17455
|
+
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync9, readFileSync as readFileSync30, readdirSync as readdirSync8, statSync as statSync5, rmSync as rmSync5 } from "node:fs";
|
|
17456
|
+
import { join as join28 } from "node:path";
|
|
17457
|
+
import { homedir as homedir11 } from "node:os";
|
|
17458
|
+
import { fileURLToPath as fileURLToPath17 } from "node:url";
|
|
17459
17459
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
17460
17460
|
function dirExists(p) {
|
|
17461
17461
|
try {
|
|
17462
|
-
return
|
|
17462
|
+
return statSync5(p).isDirectory();
|
|
17463
17463
|
} catch {
|
|
17464
17464
|
return false;
|
|
17465
17465
|
}
|
|
@@ -17468,9 +17468,9 @@ function countFiles(dir) {
|
|
|
17468
17468
|
try {
|
|
17469
17469
|
let n = 0;
|
|
17470
17470
|
const walk = (d) => {
|
|
17471
|
-
for (const e of
|
|
17471
|
+
for (const e of readdirSync8(d, { withFileTypes: true })) {
|
|
17472
17472
|
if (e.isDirectory())
|
|
17473
|
-
walk(
|
|
17473
|
+
walk(join28(d, e.name));
|
|
17474
17474
|
else
|
|
17475
17475
|
n++;
|
|
17476
17476
|
}
|
|
@@ -17484,8 +17484,8 @@ function countFiles(dir) {
|
|
|
17484
17484
|
function syncData() {
|
|
17485
17485
|
if (!dirExists(DATA_ROOT2))
|
|
17486
17486
|
mkdirSync10(DATA_ROOT2, { recursive: true });
|
|
17487
|
-
const payloadsPath =
|
|
17488
|
-
const templatesPath =
|
|
17487
|
+
const payloadsPath = join28(DATA_ROOT2, "payloads");
|
|
17488
|
+
const templatesPath = join28(DATA_ROOT2, "templates");
|
|
17489
17489
|
const hasPayloads = dirExists(payloadsPath) && countFiles(payloadsPath) > 0;
|
|
17490
17490
|
const hasTemplates = dirExists(templatesPath) && countFiles(templatesPath) > 0;
|
|
17491
17491
|
if (hasPayloads && hasTemplates) {
|
|
@@ -17495,8 +17495,8 @@ function syncData() {
|
|
|
17495
17495
|
data_root: DATA_ROOT2
|
|
17496
17496
|
};
|
|
17497
17497
|
}
|
|
17498
|
-
const localPayloads =
|
|
17499
|
-
const localTemplates =
|
|
17498
|
+
const localPayloads = join28(ROOT10, "payloads");
|
|
17499
|
+
const localTemplates = join28(ROOT10, "templates");
|
|
17500
17500
|
let payloadsSynced = false;
|
|
17501
17501
|
let templatesSynced = false;
|
|
17502
17502
|
if (!hasPayloads && dirExists(localPayloads)) {
|
|
@@ -17509,7 +17509,7 @@ function syncData() {
|
|
|
17509
17509
|
}
|
|
17510
17510
|
const gitOk = spawnSync4("git", ["--version"]).status === 0;
|
|
17511
17511
|
if (gitOk && (!dirExists(payloadsPath) || countFiles(payloadsPath) === 0 || !dirExists(templatesPath) || countFiles(templatesPath) === 0)) {
|
|
17512
|
-
const tmp =
|
|
17512
|
+
const tmp = join28(DATA_ROOT2, ".tmp-clone");
|
|
17513
17513
|
if (dirExists(tmp))
|
|
17514
17514
|
rmSync5(tmp, { recursive: true, force: true });
|
|
17515
17515
|
const r = spawnSync4("git", ["clone", "--depth", "1", "--filter=blob:none", "--sparse", GITHUB_REPO, tmp], { timeout: 120000 });
|
|
@@ -17517,11 +17517,11 @@ function syncData() {
|
|
|
17517
17517
|
const sparse = spawnSync4("git", ["-C", tmp, "sparse-checkout", "set", "payloads", "templates"], { timeout: 120000 });
|
|
17518
17518
|
if (sparse.status === 0) {
|
|
17519
17519
|
if (!dirExists(payloadsPath) || countFiles(payloadsPath) === 0) {
|
|
17520
|
-
copyDir(
|
|
17520
|
+
copyDir(join28(tmp, "payloads"), payloadsPath);
|
|
17521
17521
|
payloadsSynced = true;
|
|
17522
17522
|
}
|
|
17523
17523
|
if (!dirExists(templatesPath) || countFiles(templatesPath) === 0) {
|
|
17524
|
-
copyDir(
|
|
17524
|
+
copyDir(join28(tmp, "templates"), templatesPath);
|
|
17525
17525
|
templatesSynced = true;
|
|
17526
17526
|
}
|
|
17527
17527
|
}
|
|
@@ -17542,19 +17542,19 @@ function copyDir(src, dst) {
|
|
|
17542
17542
|
}
|
|
17543
17543
|
function manualCopy(src, dst) {
|
|
17544
17544
|
mkdirSync10(dst, { recursive: true });
|
|
17545
|
-
for (const e of
|
|
17546
|
-
const s =
|
|
17547
|
-
const d =
|
|
17545
|
+
for (const e of readdirSync8(src, { withFileTypes: true })) {
|
|
17546
|
+
const s = join28(src, e.name);
|
|
17547
|
+
const d = join28(dst, e.name);
|
|
17548
17548
|
if (e.isDirectory())
|
|
17549
17549
|
manualCopy(s, d);
|
|
17550
17550
|
else
|
|
17551
|
-
writeFileSync9(d,
|
|
17551
|
+
writeFileSync9(d, readFileSync30(s));
|
|
17552
17552
|
}
|
|
17553
17553
|
}
|
|
17554
|
-
var
|
|
17554
|
+
var ROOT10, DATA_ROOT2, GITHUB_REPO = "https://github.com/shinthink/blitzstrike.git";
|
|
17555
17555
|
var init_sync = __esm(() => {
|
|
17556
|
-
|
|
17557
|
-
DATA_ROOT2 = process.env.BLITZSTRIKE_DATA ??
|
|
17556
|
+
ROOT10 = join28(fileURLToPath17(new URL(".", import.meta.url)), "..");
|
|
17557
|
+
DATA_ROOT2 = process.env.BLITZSTRIKE_DATA ?? join28(homedir11(), ".blitzstrike", "data");
|
|
17558
17558
|
});
|
|
17559
17559
|
|
|
17560
17560
|
// src/update.ts
|
|
@@ -17599,15 +17599,15 @@ var init_update = __esm(() => {
|
|
|
17599
17599
|
});
|
|
17600
17600
|
|
|
17601
17601
|
// src/release.ts
|
|
17602
|
-
import { readFileSync as
|
|
17603
|
-
import { join as
|
|
17604
|
-
import { fileURLToPath as
|
|
17602
|
+
import { readFileSync as readFileSync32, existsSync as existsSync17 } from "node:fs";
|
|
17603
|
+
import { join as join29 } from "node:path";
|
|
17604
|
+
import { fileURLToPath as fileURLToPath18 } from "node:url";
|
|
17605
17605
|
import { execSync as execSync4 } from "node:child_process";
|
|
17606
17606
|
function validateRelease() {
|
|
17607
17607
|
const checks = [];
|
|
17608
17608
|
checks.push({ name: "package.json version", ok: true, detail: VERSION });
|
|
17609
17609
|
try {
|
|
17610
|
-
const changelog =
|
|
17610
|
+
const changelog = readFileSync32(join29(ROOT11, "CHANGELOG.md"), "utf8");
|
|
17611
17611
|
const m = changelog.match(/^##\s+\[([0-9]+\.[0-9]+\.[0-9]+)\]/m);
|
|
17612
17612
|
const changelogVersion = m?.[1] ?? null;
|
|
17613
17613
|
checks.push({
|
|
@@ -17619,7 +17619,7 @@ function validateRelease() {
|
|
|
17619
17619
|
checks.push({ name: "CHANGELOG version", ok: false, detail: "CHANGELOG.md not found" });
|
|
17620
17620
|
}
|
|
17621
17621
|
try {
|
|
17622
|
-
const tag = execSync4("git describe --tags --abbrev=0", { cwd:
|
|
17622
|
+
const tag = execSync4("git describe --tags --abbrev=0", { cwd: ROOT11, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
17623
17623
|
checks.push({ name: "Git tag", ok: tag === `v${VERSION}`, detail: tag, soft: true });
|
|
17624
17624
|
} catch {
|
|
17625
17625
|
checks.push({ name: "Git tag", ok: true, detail: "unavailable (no git/tags)", soft: true });
|
|
@@ -17639,22 +17639,22 @@ function validateRelease() {
|
|
|
17639
17639
|
return { version: VERSION, checks, consistent: checks.filter((c) => !c.soft).every((c) => c.ok) };
|
|
17640
17640
|
}
|
|
17641
17641
|
function lockfilePresent() {
|
|
17642
|
-
return
|
|
17642
|
+
return existsSync17(join29(ROOT11, "package-lock.json")) || existsSync17(join29(ROOT11, "bun.lock")) || existsSync17(join29(ROOT11, "bun.lockb"));
|
|
17643
17643
|
}
|
|
17644
|
-
var
|
|
17644
|
+
var ROOT11;
|
|
17645
17645
|
var init_release = __esm(() => {
|
|
17646
17646
|
init_version();
|
|
17647
|
-
|
|
17647
|
+
ROOT11 = join29(fileURLToPath18(new URL(".", import.meta.url)), "..");
|
|
17648
17648
|
});
|
|
17649
17649
|
|
|
17650
17650
|
// src/dependency.ts
|
|
17651
|
-
import { readFileSync as
|
|
17652
|
-
import { join as
|
|
17653
|
-
import { fileURLToPath as
|
|
17651
|
+
import { readFileSync as readFileSync33 } from "node:fs";
|
|
17652
|
+
import { join as join30 } from "node:path";
|
|
17653
|
+
import { fileURLToPath as fileURLToPath19 } from "node:url";
|
|
17654
17654
|
function checkDependencies() {
|
|
17655
17655
|
let pkg = {};
|
|
17656
17656
|
try {
|
|
17657
|
-
pkg = JSON.parse(
|
|
17657
|
+
pkg = JSON.parse(readFileSync33(join30(ROOT12, "package.json"), "utf8"));
|
|
17658
17658
|
} catch {
|
|
17659
17659
|
return { install_scripts: [], git_dependencies: [], total_dependencies: 0, safe: false };
|
|
17660
17660
|
}
|
|
@@ -17675,16 +17675,16 @@ function checkDependencies() {
|
|
|
17675
17675
|
safe: installScripts.length === 0 && gitDependencies.length === 0
|
|
17676
17676
|
};
|
|
17677
17677
|
}
|
|
17678
|
-
var
|
|
17678
|
+
var ROOT12;
|
|
17679
17679
|
var init_dependency = __esm(() => {
|
|
17680
|
-
|
|
17680
|
+
ROOT12 = join30(fileURLToPath19(new URL(".", import.meta.url)), "..");
|
|
17681
17681
|
});
|
|
17682
17682
|
|
|
17683
17683
|
// src/cli.ts
|
|
17684
|
-
import { readFileSync as
|
|
17685
|
-
import { join as
|
|
17686
|
-
import { homedir as
|
|
17687
|
-
import { fileURLToPath as
|
|
17684
|
+
import { readFileSync as readFileSync34, existsSync as existsSync18, writeFileSync as writeFileSync10, mkdirSync as mkdirSync11 } from "node:fs";
|
|
17685
|
+
import { join as join31, dirname as dirname6 } from "node:path";
|
|
17686
|
+
import { homedir as homedir12 } from "node:os";
|
|
17687
|
+
import { fileURLToPath as fileURLToPath20 } from "node:url";
|
|
17688
17688
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
17689
17689
|
function which(cmd) {
|
|
17690
17690
|
return spawnSync5("sh", ["-c", 'command -v "$1" >/dev/null 2>&1', "sh", cmd]).status === 0;
|
|
@@ -17727,7 +17727,7 @@ async function runDoctor() {
|
|
|
17727
17727
|
detail: h1 ? `X-HackerOne-Research: ${h1}` : "H1_USERNAME not set",
|
|
17728
17728
|
fix: h1 ? undefined : "export H1_USERNAME=<your-hackerone-username> (adds X-HackerOne-Research to outbound requests)"
|
|
17729
17729
|
});
|
|
17730
|
-
const dataOk =
|
|
17730
|
+
const dataOk = existsSync18(join31(ROOT13, "chains.json")) && existsSync18(join31(ROOT13, "tools-catalog.json"));
|
|
17731
17731
|
issues.push({
|
|
17732
17732
|
name: "Data layers (chains + tools-catalog)",
|
|
17733
17733
|
status: dataOk ? "ok" : "fail",
|
|
@@ -17778,21 +17778,21 @@ BlitzStrike — ${verdict}`);
|
|
|
17778
17778
|
function resolveCommand() {
|
|
17779
17779
|
if (which("blitzstrike"))
|
|
17780
17780
|
return { command: "blitzstrike", args: ["serve", "--mcp"] };
|
|
17781
|
-
const src =
|
|
17782
|
-
if (which("bun") &&
|
|
17781
|
+
const src = join31(ROOT13, "src", "index.ts");
|
|
17782
|
+
if (which("bun") && existsSync18(src))
|
|
17783
17783
|
return { command: "bun", args: ["run", src, "serve", "--mcp"] };
|
|
17784
17784
|
if (which("npx"))
|
|
17785
17785
|
return { command: "npx", args: ["-y", "blitzstrike", "serve", "--mcp"] };
|
|
17786
17786
|
if (which("bunx"))
|
|
17787
17787
|
return { command: "bunx", args: ["blitzstrike", "serve", "--mcp"] };
|
|
17788
|
-
const dist =
|
|
17789
|
-
if (
|
|
17788
|
+
const dist = join31(ROOT13, "dist", "index.js");
|
|
17789
|
+
if (existsSync18(dist))
|
|
17790
17790
|
return { command: "bun", args: [dist, "serve", "--mcp"] };
|
|
17791
17791
|
return { command: "npx", args: ["-y", "blitzstrike", "serve", "--mcp"] };
|
|
17792
17792
|
}
|
|
17793
17793
|
function readJson(p) {
|
|
17794
17794
|
try {
|
|
17795
|
-
return JSON.parse(
|
|
17795
|
+
return JSON.parse(readFileSync34(p, "utf8"));
|
|
17796
17796
|
} catch {
|
|
17797
17797
|
return null;
|
|
17798
17798
|
}
|
|
@@ -17800,7 +17800,7 @@ function readJson(p) {
|
|
|
17800
17800
|
function jsonMcpServersWrite(p) {
|
|
17801
17801
|
return (command, args) => {
|
|
17802
17802
|
const dir = dirname6(p);
|
|
17803
|
-
if (!
|
|
17803
|
+
if (!existsSync18(dir))
|
|
17804
17804
|
mkdirSync11(dir, { recursive: true });
|
|
17805
17805
|
const existing = readJson(p) ?? {};
|
|
17806
17806
|
existing.mcpServers = {
|
|
@@ -17813,7 +17813,7 @@ function jsonMcpServersWrite(p) {
|
|
|
17813
17813
|
function opencodeWrite(p) {
|
|
17814
17814
|
return (command, args) => {
|
|
17815
17815
|
const dir = dirname6(p);
|
|
17816
|
-
if (!
|
|
17816
|
+
if (!existsSync18(dir))
|
|
17817
17817
|
mkdirSync11(dir, { recursive: true });
|
|
17818
17818
|
const existing = readJson(p) ?? {};
|
|
17819
17819
|
existing.mcp = {
|
|
@@ -17825,26 +17825,26 @@ function opencodeWrite(p) {
|
|
|
17825
17825
|
};
|
|
17826
17826
|
}
|
|
17827
17827
|
function copyOpenCodeAgents() {
|
|
17828
|
-
const srcDir =
|
|
17829
|
-
const dstDir =
|
|
17830
|
-
if (!
|
|
17828
|
+
const srcDir = join31(ROOT13, "opencode-agents");
|
|
17829
|
+
const dstDir = join31(homedir12(), ".config", "opencode", "agents");
|
|
17830
|
+
if (!existsSync18(srcDir))
|
|
17831
17831
|
return;
|
|
17832
|
-
if (!
|
|
17832
|
+
if (!existsSync18(dstDir))
|
|
17833
17833
|
mkdirSync11(dstDir, { recursive: true });
|
|
17834
17834
|
for (const f of ["Blitz Strike.md", "Blitz.md", "Eagle Eye.md", "Strike.md"]) {
|
|
17835
|
-
const src =
|
|
17836
|
-
const dst =
|
|
17837
|
-
if (
|
|
17838
|
-
writeFileSync10(dst,
|
|
17835
|
+
const src = join31(srcDir, f);
|
|
17836
|
+
const dst = join31(dstDir, f);
|
|
17837
|
+
if (existsSync18(src)) {
|
|
17838
|
+
writeFileSync10(dst, readFileSync34(src, "utf8"));
|
|
17839
17839
|
}
|
|
17840
17840
|
}
|
|
17841
17841
|
}
|
|
17842
17842
|
function codexWrite(p) {
|
|
17843
17843
|
return (command, args) => {
|
|
17844
17844
|
const dir = dirname6(p);
|
|
17845
|
-
if (!
|
|
17845
|
+
if (!existsSync18(dir))
|
|
17846
17846
|
mkdirSync11(dir, { recursive: true });
|
|
17847
|
-
let existing =
|
|
17847
|
+
let existing = existsSync18(p) ? readFileSync34(p, "utf8") : "";
|
|
17848
17848
|
if (!existing.trimEnd().endsWith(`
|
|
17849
17849
|
`))
|
|
17850
17850
|
existing += `
|
|
@@ -17861,9 +17861,9 @@ args = ${JSON.stringify(args)}
|
|
|
17861
17861
|
function hermesWrite(p) {
|
|
17862
17862
|
return (command, args) => {
|
|
17863
17863
|
const dir = dirname6(p);
|
|
17864
|
-
if (!
|
|
17864
|
+
if (!existsSync18(dir))
|
|
17865
17865
|
mkdirSync11(dir, { recursive: true });
|
|
17866
|
-
let existing =
|
|
17866
|
+
let existing = existsSync18(p) ? readFileSync34(p, "utf8") : "";
|
|
17867
17867
|
existing = existing.replace(/^ blitzstrike:\n(?: .*\n?)*/m, "");
|
|
17868
17868
|
if (!existing.trimEnd().endsWith(`
|
|
17869
17869
|
`))
|
|
@@ -17888,76 +17888,76 @@ mcp_servers:
|
|
|
17888
17888
|
};
|
|
17889
17889
|
}
|
|
17890
17890
|
function detectAgents() {
|
|
17891
|
-
const home =
|
|
17891
|
+
const home = homedir12();
|
|
17892
17892
|
const agents = [];
|
|
17893
|
-
const claudeJson =
|
|
17893
|
+
const claudeJson = join31(home, ".claude.json");
|
|
17894
17894
|
agents.push({
|
|
17895
17895
|
name: "Claude Code",
|
|
17896
17896
|
detectPath: claudeJson,
|
|
17897
|
-
installed: () =>
|
|
17897
|
+
installed: () => existsSync18(claudeJson) || which("claude"),
|
|
17898
17898
|
write: jsonMcpServersWrite(claudeJson)
|
|
17899
17899
|
});
|
|
17900
|
-
const claudeDesktop =
|
|
17900
|
+
const claudeDesktop = join31(home, ".config", "Claude", "claude_desktop_config.json");
|
|
17901
17901
|
agents.push({
|
|
17902
17902
|
name: "Claude Desktop",
|
|
17903
17903
|
detectPath: claudeDesktop,
|
|
17904
|
-
installed: () =>
|
|
17904
|
+
installed: () => existsSync18(claudeDesktop),
|
|
17905
17905
|
write: jsonMcpServersWrite(claudeDesktop)
|
|
17906
17906
|
});
|
|
17907
|
-
const cursor =
|
|
17907
|
+
const cursor = join31(home, ".cursor", "mcp.json");
|
|
17908
17908
|
agents.push({
|
|
17909
17909
|
name: "Cursor",
|
|
17910
17910
|
detectPath: cursor,
|
|
17911
|
-
installed: () =>
|
|
17911
|
+
installed: () => existsSync18(join31(home, ".cursor")) || which("cursor"),
|
|
17912
17912
|
write: jsonMcpServersWrite(cursor)
|
|
17913
17913
|
});
|
|
17914
|
-
const opencode =
|
|
17914
|
+
const opencode = join31(home, ".config", "opencode", "opencode.jsonc");
|
|
17915
17915
|
agents.push({
|
|
17916
17916
|
name: "OpenCode",
|
|
17917
17917
|
detectPath: opencode,
|
|
17918
|
-
installed: () =>
|
|
17918
|
+
installed: () => existsSync18(join31(home, ".config", "opencode")) || which("opencode"),
|
|
17919
17919
|
write: opencodeWrite(opencode)
|
|
17920
17920
|
});
|
|
17921
|
-
const codex =
|
|
17921
|
+
const codex = join31(home, ".codex", "config.toml");
|
|
17922
17922
|
agents.push({
|
|
17923
17923
|
name: "Codex",
|
|
17924
17924
|
detectPath: codex,
|
|
17925
|
-
installed: () =>
|
|
17925
|
+
installed: () => existsSync18(join31(home, ".codex")) || which("codex"),
|
|
17926
17926
|
write: codexWrite(codex)
|
|
17927
17927
|
});
|
|
17928
|
-
const hermes =
|
|
17928
|
+
const hermes = join31(home, ".hermes", "config.yaml");
|
|
17929
17929
|
agents.push({
|
|
17930
17930
|
name: "Hermes",
|
|
17931
17931
|
detectPath: hermes,
|
|
17932
|
-
installed: () =>
|
|
17932
|
+
installed: () => existsSync18(join31(home, ".hermes")) || which("hermes"),
|
|
17933
17933
|
write: hermesWrite(hermes)
|
|
17934
17934
|
});
|
|
17935
|
-
const gemini =
|
|
17935
|
+
const gemini = join31(home, ".gemini", "settings.json");
|
|
17936
17936
|
agents.push({
|
|
17937
17937
|
name: "Gemini CLI",
|
|
17938
17938
|
detectPath: gemini,
|
|
17939
|
-
installed: () =>
|
|
17939
|
+
installed: () => existsSync18(join31(home, ".gemini")) || which("gemini"),
|
|
17940
17940
|
write: jsonMcpServersWrite(gemini)
|
|
17941
17941
|
});
|
|
17942
|
-
const windsurf =
|
|
17942
|
+
const windsurf = join31(home, ".codeium", "windsurf", "mcp_config.json");
|
|
17943
17943
|
agents.push({
|
|
17944
17944
|
name: "Windsurf",
|
|
17945
17945
|
detectPath: windsurf,
|
|
17946
|
-
installed: () =>
|
|
17946
|
+
installed: () => existsSync18(join31(home, ".codeium")) || which("windsurf"),
|
|
17947
17947
|
write: jsonMcpServersWrite(windsurf)
|
|
17948
17948
|
});
|
|
17949
|
-
const copilot =
|
|
17949
|
+
const copilot = join31(home, ".copilot", "mcp.json");
|
|
17950
17950
|
agents.push({
|
|
17951
17951
|
name: "Copilot",
|
|
17952
17952
|
detectPath: copilot,
|
|
17953
|
-
installed: () =>
|
|
17953
|
+
installed: () => existsSync18(join31(home, ".copilot")),
|
|
17954
17954
|
write: jsonMcpServersWrite(copilot)
|
|
17955
17955
|
});
|
|
17956
|
-
const cline =
|
|
17956
|
+
const cline = join31(home, ".cline", "mcp_settings.json");
|
|
17957
17957
|
agents.push({
|
|
17958
17958
|
name: "Cline",
|
|
17959
17959
|
detectPath: cline,
|
|
17960
|
-
installed: () =>
|
|
17960
|
+
installed: () => existsSync18(join31(home, ".cline")),
|
|
17961
17961
|
write: jsonMcpServersWrite(cline)
|
|
17962
17962
|
});
|
|
17963
17963
|
return agents;
|
|
@@ -18069,13 +18069,13 @@ Failed (${failedList.length}) — reason per tool:`);
|
|
|
18069
18069
|
Common causes: missing toolchain, pip/git network failures, or very heavy builds. ` + `Re-run after installing the missing toolchain — failed tools are skipped, not fatal.`);
|
|
18070
18070
|
}
|
|
18071
18071
|
}
|
|
18072
|
-
var
|
|
18072
|
+
var ROOT13;
|
|
18073
18073
|
var init_cli = __esm(() => {
|
|
18074
18074
|
init_catalog();
|
|
18075
18075
|
init_release();
|
|
18076
18076
|
init_dependency();
|
|
18077
18077
|
init_mcp_status();
|
|
18078
|
-
|
|
18078
|
+
ROOT13 = join31(fileURLToPath20(new URL(".", import.meta.url)), "..");
|
|
18079
18079
|
});
|
|
18080
18080
|
|
|
18081
18081
|
// node_modules/zod/v3/helpers/util.js
|
|
@@ -32713,7 +32713,8 @@ class StdioServerTransport {
|
|
|
32713
32713
|
|
|
32714
32714
|
// src/server.ts
|
|
32715
32715
|
init_scanner();
|
|
32716
|
-
import { readFileSync as
|
|
32716
|
+
import { readFileSync as readFileSync31 } from "node:fs";
|
|
32717
|
+
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
32717
32718
|
|
|
32718
32719
|
// src/review-harness.ts
|
|
32719
32720
|
init_scanner();
|
|
@@ -32879,9 +32880,9 @@ async function nvdLookup(cveId) {
|
|
|
32879
32880
|
|
|
32880
32881
|
// src/orchestrator.ts
|
|
32881
32882
|
init_scanner();
|
|
32882
|
-
import { readFileSync as
|
|
32883
|
-
import { join as
|
|
32884
|
-
import { fileURLToPath as
|
|
32883
|
+
import { readFileSync as readFileSync14, existsSync as existsSync9, statSync as statSync3 } from "node:fs";
|
|
32884
|
+
import { join as join15 } from "node:path";
|
|
32885
|
+
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
32885
32886
|
|
|
32886
32887
|
// src/memory.ts
|
|
32887
32888
|
import { readFileSync as readFileSync3, appendFileSync, mkdirSync, existsSync, writeFileSync } from "node:fs";
|
|
@@ -36295,10 +36296,323 @@ init_version();
|
|
|
36295
36296
|
// src/hunting-intel.ts
|
|
36296
36297
|
import { execFileSync } from "node:child_process";
|
|
36297
36298
|
import { resolve4, Resolver } from "node:dns/promises";
|
|
36298
|
-
import { readFileSync as
|
|
36299
|
+
import { readFileSync as readFileSync12 } from "node:fs";
|
|
36300
|
+
import { join as join13 } from "node:path";
|
|
36301
|
+
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
36302
|
+
|
|
36303
|
+
// src/nuclei-corpus.ts
|
|
36304
|
+
import { existsSync as existsSync8, readFileSync as readFileSync11, readdirSync as readdirSync5, statSync as statSync2 } from "node:fs";
|
|
36299
36305
|
import { join as join12 } from "node:path";
|
|
36306
|
+
import { homedir as homedir8 } from "node:os";
|
|
36300
36307
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
36301
36308
|
var ROOT4 = join12(fileURLToPath6(new URL(".", import.meta.url)), "..");
|
|
36309
|
+
var GENERIC = new Set([
|
|
36310
|
+
"php",
|
|
36311
|
+
"python",
|
|
36312
|
+
"java",
|
|
36313
|
+
"javascript",
|
|
36314
|
+
"node",
|
|
36315
|
+
"nodejs",
|
|
36316
|
+
"ruby",
|
|
36317
|
+
"perl",
|
|
36318
|
+
"go",
|
|
36319
|
+
"golang",
|
|
36320
|
+
"rust",
|
|
36321
|
+
"html",
|
|
36322
|
+
"css",
|
|
36323
|
+
"xml",
|
|
36324
|
+
"json",
|
|
36325
|
+
"shell",
|
|
36326
|
+
"bash",
|
|
36327
|
+
"sql",
|
|
36328
|
+
"apache",
|
|
36329
|
+
"nginx",
|
|
36330
|
+
"iis",
|
|
36331
|
+
"tomcat",
|
|
36332
|
+
"jboss",
|
|
36333
|
+
"weblogic",
|
|
36334
|
+
"websphere",
|
|
36335
|
+
"litespeed",
|
|
36336
|
+
"lighttpd",
|
|
36337
|
+
"caddy",
|
|
36338
|
+
"mysql",
|
|
36339
|
+
"mariadb",
|
|
36340
|
+
"postgres",
|
|
36341
|
+
"postgresql",
|
|
36342
|
+
"sqlite",
|
|
36343
|
+
"mongodb",
|
|
36344
|
+
"redis",
|
|
36345
|
+
"memcached",
|
|
36346
|
+
"elasticsearch",
|
|
36347
|
+
"elastic",
|
|
36348
|
+
"cassandra",
|
|
36349
|
+
"content",
|
|
36350
|
+
"console",
|
|
36351
|
+
"directory",
|
|
36352
|
+
"manager",
|
|
36353
|
+
"panel",
|
|
36354
|
+
"admin",
|
|
36355
|
+
"login",
|
|
36356
|
+
"logout",
|
|
36357
|
+
"config",
|
|
36358
|
+
"configuration",
|
|
36359
|
+
"upload",
|
|
36360
|
+
"download",
|
|
36361
|
+
"view",
|
|
36362
|
+
"list",
|
|
36363
|
+
"index",
|
|
36364
|
+
"search",
|
|
36365
|
+
"read",
|
|
36366
|
+
"write",
|
|
36367
|
+
"text",
|
|
36368
|
+
"data",
|
|
36369
|
+
"utils",
|
|
36370
|
+
"utility",
|
|
36371
|
+
"api",
|
|
36372
|
+
"web",
|
|
36373
|
+
"app",
|
|
36374
|
+
"application",
|
|
36375
|
+
"site",
|
|
36376
|
+
"page",
|
|
36377
|
+
"portal",
|
|
36378
|
+
"dashboard",
|
|
36379
|
+
"interface",
|
|
36380
|
+
"module",
|
|
36381
|
+
"plugin",
|
|
36382
|
+
"component",
|
|
36383
|
+
"service",
|
|
36384
|
+
"client",
|
|
36385
|
+
"user",
|
|
36386
|
+
"account",
|
|
36387
|
+
"session",
|
|
36388
|
+
"token",
|
|
36389
|
+
"password",
|
|
36390
|
+
"credential",
|
|
36391
|
+
"key",
|
|
36392
|
+
"secret",
|
|
36393
|
+
"auth",
|
|
36394
|
+
"request",
|
|
36395
|
+
"response",
|
|
36396
|
+
"header",
|
|
36397
|
+
"body",
|
|
36398
|
+
"function",
|
|
36399
|
+
"script",
|
|
36400
|
+
"code",
|
|
36401
|
+
"execute",
|
|
36402
|
+
"command",
|
|
36403
|
+
"injection",
|
|
36404
|
+
"remote",
|
|
36405
|
+
"local",
|
|
36406
|
+
"arbitrary",
|
|
36407
|
+
"attacker",
|
|
36408
|
+
"unauth",
|
|
36409
|
+
"authenticated",
|
|
36410
|
+
"unauthenticated",
|
|
36411
|
+
"version",
|
|
36412
|
+
"versions",
|
|
36413
|
+
"prior",
|
|
36414
|
+
"before",
|
|
36415
|
+
"after",
|
|
36416
|
+
"multiple",
|
|
36417
|
+
"vulnerable",
|
|
36418
|
+
"vulnerability",
|
|
36419
|
+
"vulnerabilities",
|
|
36420
|
+
"security",
|
|
36421
|
+
"issue",
|
|
36422
|
+
"issues",
|
|
36423
|
+
"exploit",
|
|
36424
|
+
"exploits",
|
|
36425
|
+
"denial",
|
|
36426
|
+
"escalation",
|
|
36427
|
+
"disclosure",
|
|
36428
|
+
"exposure",
|
|
36429
|
+
"bypass",
|
|
36430
|
+
"override",
|
|
36431
|
+
"flaw",
|
|
36432
|
+
"bug",
|
|
36433
|
+
"error",
|
|
36434
|
+
"warning",
|
|
36435
|
+
"info",
|
|
36436
|
+
"information",
|
|
36437
|
+
"access",
|
|
36438
|
+
"control",
|
|
36439
|
+
"privilege",
|
|
36440
|
+
"leading",
|
|
36441
|
+
"lead",
|
|
36442
|
+
"allows",
|
|
36443
|
+
"affects",
|
|
36444
|
+
"affected",
|
|
36445
|
+
"powered",
|
|
36446
|
+
"power",
|
|
36447
|
+
"by",
|
|
36448
|
+
"software",
|
|
36449
|
+
"systems",
|
|
36450
|
+
"technologies",
|
|
36451
|
+
"solutions",
|
|
36452
|
+
"enterprise",
|
|
36453
|
+
"professional",
|
|
36454
|
+
"studio",
|
|
36455
|
+
"labs",
|
|
36456
|
+
"network",
|
|
36457
|
+
"networks",
|
|
36458
|
+
"cloud",
|
|
36459
|
+
"hosting",
|
|
36460
|
+
"platform",
|
|
36461
|
+
"framework",
|
|
36462
|
+
"library",
|
|
36463
|
+
"inc",
|
|
36464
|
+
"ltd",
|
|
36465
|
+
"llc",
|
|
36466
|
+
"corp",
|
|
36467
|
+
"co",
|
|
36468
|
+
"company",
|
|
36469
|
+
"free",
|
|
36470
|
+
"open",
|
|
36471
|
+
"source",
|
|
36472
|
+
"project",
|
|
36473
|
+
"wordpress",
|
|
36474
|
+
"joomla",
|
|
36475
|
+
"drupal",
|
|
36476
|
+
"magento",
|
|
36477
|
+
"shopify",
|
|
36478
|
+
"prestashop",
|
|
36479
|
+
"zencart",
|
|
36480
|
+
"opencart",
|
|
36481
|
+
"red",
|
|
36482
|
+
"hat",
|
|
36483
|
+
"magic",
|
|
36484
|
+
"hue",
|
|
36485
|
+
"get",
|
|
36486
|
+
"set",
|
|
36487
|
+
"use",
|
|
36488
|
+
"run",
|
|
36489
|
+
"top",
|
|
36490
|
+
"new"
|
|
36491
|
+
]);
|
|
36492
|
+
function tokens(text) {
|
|
36493
|
+
const out = [];
|
|
36494
|
+
for (const t of text.toLowerCase().split(/[^a-z0-9]+/)) {
|
|
36495
|
+
if (!t || t.length < 3)
|
|
36496
|
+
continue;
|
|
36497
|
+
if (/^\d+(\.\d+)*$/.test(t))
|
|
36498
|
+
continue;
|
|
36499
|
+
if (GENERIC.has(t))
|
|
36500
|
+
continue;
|
|
36501
|
+
out.push(t);
|
|
36502
|
+
}
|
|
36503
|
+
return out;
|
|
36504
|
+
}
|
|
36505
|
+
function firstMatch(txt, re) {
|
|
36506
|
+
const m = re.exec(txt);
|
|
36507
|
+
return m ? m[1].trim() : null;
|
|
36508
|
+
}
|
|
36509
|
+
function parseTemplate(text) {
|
|
36510
|
+
const cve = firstMatch(text, /^id:\s*(\S+)/m);
|
|
36511
|
+
if (!cve || !cve.toUpperCase().startsWith("CVE-"))
|
|
36512
|
+
return null;
|
|
36513
|
+
const name = firstMatch(text, /^\s*name:\s*(.+)$/m) ?? cve;
|
|
36514
|
+
const severity = firstMatch(text, /^\s*severity:\s*(\w+)/m) ?? undefined;
|
|
36515
|
+
const epssStr = firstMatch(text, /^\s*epss-score:\s*([\d.]+)/m);
|
|
36516
|
+
const cwe = firstMatch(text, /^\s*cwe-id:\s*(CWE-\d+)/m) ?? undefined;
|
|
36517
|
+
let prod = name.split(/\s+-\s+|:\s+/, 1)[0].trim();
|
|
36518
|
+
prod = prod.replace(/[\s<>=~]+[vV]?[\d][\w.\-]*.*$/, "").trim();
|
|
36519
|
+
const kw = new Set(tokens(prod));
|
|
36520
|
+
for (const q of text.matchAll(/^\s*(?:fofa|shodan)-query:\s*(.+)$/gm)) {
|
|
36521
|
+
for (const m of q[1].matchAll(/(?:body|title|header|http\.html|html)\s*=\s*"([^"]+)"/g)) {
|
|
36522
|
+
for (const t of tokens(m[1]))
|
|
36523
|
+
kw.add(t);
|
|
36524
|
+
}
|
|
36525
|
+
}
|
|
36526
|
+
if (kw.size === 0)
|
|
36527
|
+
for (const t of tokens(name).slice(0, 3))
|
|
36528
|
+
kw.add(t);
|
|
36529
|
+
const kwSorted = [...kw].sort().slice(0, 8);
|
|
36530
|
+
const match = kwSorted.length ? `\\b(?:${kwSorted.map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})\\b` : undefined;
|
|
36531
|
+
return {
|
|
36532
|
+
cve,
|
|
36533
|
+
name,
|
|
36534
|
+
product: prod,
|
|
36535
|
+
severity,
|
|
36536
|
+
epss: parseFloat(epssStr ?? "0") || 0,
|
|
36537
|
+
cwe,
|
|
36538
|
+
match
|
|
36539
|
+
};
|
|
36540
|
+
}
|
|
36541
|
+
function findTemplatesDir() {
|
|
36542
|
+
const candidates = [join12(homedir8(), "nuclei-templates"), join12(homedir8(), ".nuclei-templates"), "/root/nuclei-templates"];
|
|
36543
|
+
for (const c of candidates)
|
|
36544
|
+
if (existsSync8(join12(c, "http", "cves")))
|
|
36545
|
+
return c;
|
|
36546
|
+
return null;
|
|
36547
|
+
}
|
|
36548
|
+
function loadLiveCorpus() {
|
|
36549
|
+
const dir = findTemplatesDir();
|
|
36550
|
+
if (!dir)
|
|
36551
|
+
return [];
|
|
36552
|
+
const out = [];
|
|
36553
|
+
const walk = (d) => {
|
|
36554
|
+
let entries;
|
|
36555
|
+
try {
|
|
36556
|
+
entries = readdirSync5(d);
|
|
36557
|
+
} catch {
|
|
36558
|
+
return;
|
|
36559
|
+
}
|
|
36560
|
+
for (const name of entries) {
|
|
36561
|
+
const full = join12(d, name);
|
|
36562
|
+
let st;
|
|
36563
|
+
try {
|
|
36564
|
+
st = statSync2(full);
|
|
36565
|
+
} catch {
|
|
36566
|
+
continue;
|
|
36567
|
+
}
|
|
36568
|
+
if (st.isDirectory())
|
|
36569
|
+
walk(full);
|
|
36570
|
+
else if (name.endsWith(".yaml")) {
|
|
36571
|
+
try {
|
|
36572
|
+
const e = parseTemplate(readFileSync11(full, "utf8"));
|
|
36573
|
+
if (e)
|
|
36574
|
+
out.push(e);
|
|
36575
|
+
} catch {}
|
|
36576
|
+
}
|
|
36577
|
+
}
|
|
36578
|
+
};
|
|
36579
|
+
walk(join12(dir, "http", "cves"));
|
|
36580
|
+
return out;
|
|
36581
|
+
}
|
|
36582
|
+
var cache = null;
|
|
36583
|
+
function invalidateCorpusCache() {
|
|
36584
|
+
cache = null;
|
|
36585
|
+
}
|
|
36586
|
+
function loadCorpusEntries() {
|
|
36587
|
+
if (cache)
|
|
36588
|
+
return cache;
|
|
36589
|
+
const live = loadLiveCorpus();
|
|
36590
|
+
if (live.length > 0) {
|
|
36591
|
+
cache = live;
|
|
36592
|
+
return live;
|
|
36593
|
+
}
|
|
36594
|
+
try {
|
|
36595
|
+
const data = JSON.parse(readFileSync11(join12(ROOT4, "intelligence", "cve-corpus.json"), "utf8"));
|
|
36596
|
+
cache = (data.cves ?? []).map((c) => ({
|
|
36597
|
+
cve: String(c.cve ?? ""),
|
|
36598
|
+
name: String(c.name ?? ""),
|
|
36599
|
+
product: String(c.product ?? ""),
|
|
36600
|
+
severity: typeof c.severity === "string" ? c.severity : undefined,
|
|
36601
|
+
epss: typeof c.epss === "number" ? c.epss : parseFloat(String(c.epss ?? "0")) || 0,
|
|
36602
|
+
cwe: typeof c.cwe === "string" ? c.cwe : undefined,
|
|
36603
|
+
match: typeof c.match === "string" ? c.match : undefined
|
|
36604
|
+
}));
|
|
36605
|
+
return cache;
|
|
36606
|
+
} catch {
|
|
36607
|
+
return [];
|
|
36608
|
+
}
|
|
36609
|
+
}
|
|
36610
|
+
function corpusSourceIsLive() {
|
|
36611
|
+
return findTemplatesDir() !== null;
|
|
36612
|
+
}
|
|
36613
|
+
|
|
36614
|
+
// src/hunting-intel.ts
|
|
36615
|
+
var ROOT5 = join13(fileURLToPath7(new URL(".", import.meta.url)), "..");
|
|
36302
36616
|
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;
|
|
36303
36617
|
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;
|
|
36304
36618
|
function isValidHostname(host) {
|
|
@@ -36372,10 +36686,25 @@ async function resolveCheck(host) {
|
|
|
36372
36686
|
};
|
|
36373
36687
|
}
|
|
36374
36688
|
function loadWatchlist() {
|
|
36375
|
-
const raw =
|
|
36689
|
+
const raw = readFileSync12(join13(ROOT5, "intelligence", "watchlist.json"), "utf8");
|
|
36376
36690
|
const data = JSON.parse(raw);
|
|
36377
36691
|
return { cwe_frequency: data.cwe_frequency ?? [], cve_watchlist: data.cve_watchlist ?? [] };
|
|
36378
36692
|
}
|
|
36693
|
+
function loadCorpus() {
|
|
36694
|
+
return loadCorpusEntries().map((c) => ({
|
|
36695
|
+
cve: c.cve,
|
|
36696
|
+
name: c.name,
|
|
36697
|
+
product: c.product,
|
|
36698
|
+
class: "",
|
|
36699
|
+
epss: c.epss,
|
|
36700
|
+
reports: 0,
|
|
36701
|
+
fingerprint: c.product,
|
|
36702
|
+
match: c.match,
|
|
36703
|
+
fixed_in: null,
|
|
36704
|
+
version_key: null,
|
|
36705
|
+
severity: c.severity
|
|
36706
|
+
}));
|
|
36707
|
+
}
|
|
36379
36708
|
function fmtPayout(min, max) {
|
|
36380
36709
|
if (min == null || max == null)
|
|
36381
36710
|
return "n/a";
|
|
@@ -36417,40 +36746,51 @@ function semverLt(a, b) {
|
|
|
36417
36746
|
}
|
|
36418
36747
|
return false;
|
|
36419
36748
|
}
|
|
36420
|
-
function watchlistCveMatches(techs, headers = {}, body = "", versions = []) {
|
|
36749
|
+
function watchlistCveMatches(techs, headers = {}, body = "", versions = [], max = 20) {
|
|
36421
36750
|
const { cve_watchlist } = loadWatchlist();
|
|
36751
|
+
const corpus = loadCorpus();
|
|
36422
36752
|
const haystack = `${techs.join(" ")} ${Object.keys(headers).join(" ")} ${Object.values(headers).join(" ")} ${body}`.toLowerCase();
|
|
36423
|
-
|
|
36753
|
+
const curated = new Map(cve_watchlist.map((c) => [c.cve, c]));
|
|
36754
|
+
const merged = [...corpus.filter((c) => !curated.has(c.cve)), ...cve_watchlist];
|
|
36755
|
+
const matched = merged.filter((c) => {
|
|
36424
36756
|
const m = c.match;
|
|
36425
36757
|
if (!m)
|
|
36426
36758
|
return false;
|
|
36427
|
-
let
|
|
36759
|
+
let ok = false;
|
|
36428
36760
|
try {
|
|
36429
|
-
|
|
36761
|
+
ok = new RegExp(m, "i").test(haystack);
|
|
36430
36762
|
} catch {
|
|
36431
|
-
|
|
36763
|
+
ok = false;
|
|
36432
36764
|
}
|
|
36433
|
-
if (!
|
|
36765
|
+
if (!ok)
|
|
36434
36766
|
return false;
|
|
36435
36767
|
const fixedIn = c.fixed_in;
|
|
36436
36768
|
const vkey = c.version_key;
|
|
36437
36769
|
if (fixedIn && vkey) {
|
|
36438
36770
|
const v = versions.find((x) => x.product.toLowerCase().includes(vkey.toLowerCase()));
|
|
36439
|
-
if (v?.version && !semverLt(v.version, fixedIn))
|
|
36771
|
+
if (v?.version && !semverLt(v.version, fixedIn))
|
|
36440
36772
|
return false;
|
|
36441
|
-
}
|
|
36442
36773
|
}
|
|
36443
36774
|
return true;
|
|
36444
36775
|
});
|
|
36776
|
+
const sevRank = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
36777
|
+
matched.sort((a, b) => {
|
|
36778
|
+
const ea = a.epss ?? 0;
|
|
36779
|
+
const eb = b.epss ?? 0;
|
|
36780
|
+
if (ea !== eb)
|
|
36781
|
+
return eb - ea;
|
|
36782
|
+
return (sevRank[a.severity ?? ""] ?? 9) - (sevRank[b.severity ?? ""] ?? 9);
|
|
36783
|
+
});
|
|
36784
|
+
return matched.slice(0, max);
|
|
36445
36785
|
}
|
|
36446
36786
|
|
|
36447
36787
|
// src/surface-map.ts
|
|
36448
|
-
import { readFileSync as
|
|
36449
|
-
import { join as
|
|
36450
|
-
import { fileURLToPath as
|
|
36451
|
-
var
|
|
36788
|
+
import { readFileSync as readFileSync13 } from "node:fs";
|
|
36789
|
+
import { join as join14 } from "node:path";
|
|
36790
|
+
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
36791
|
+
var ROOT6 = join14(fileURLToPath8(new URL(".", import.meta.url)), "..");
|
|
36452
36792
|
function load2() {
|
|
36453
|
-
const raw =
|
|
36793
|
+
const raw = readFileSync13(join14(ROOT6, "intelligence", "surface-map.json"), "utf8");
|
|
36454
36794
|
return JSON.parse(raw);
|
|
36455
36795
|
}
|
|
36456
36796
|
function surfaceMap(hint = "") {
|
|
@@ -37034,7 +37374,7 @@ function classifyTarget(target) {
|
|
|
37034
37374
|
if (/^https?:\/\//i.test(target))
|
|
37035
37375
|
return { kind: "live", target };
|
|
37036
37376
|
try {
|
|
37037
|
-
if (
|
|
37377
|
+
if (existsSync9(target) && (statSync3(target).isDirectory() || statSync3(target).isFile())) {
|
|
37038
37378
|
return { kind: "source", target };
|
|
37039
37379
|
}
|
|
37040
37380
|
} catch {}
|
|
@@ -37050,9 +37390,9 @@ function loadChains() {
|
|
|
37050
37390
|
if (_chainsCache)
|
|
37051
37391
|
return _chainsCache;
|
|
37052
37392
|
try {
|
|
37053
|
-
const dir =
|
|
37054
|
-
const path =
|
|
37055
|
-
const raw = JSON.parse(
|
|
37393
|
+
const dir = join15(fileURLToPath9(new URL(".", import.meta.url)), "..");
|
|
37394
|
+
const path = join15(dir, "chains.json");
|
|
37395
|
+
const raw = JSON.parse(readFileSync14(path, "utf8"));
|
|
37056
37396
|
_chainsCache = raw.chains ?? [];
|
|
37057
37397
|
return _chainsCache;
|
|
37058
37398
|
} catch {
|
|
@@ -37175,7 +37515,7 @@ function runEngagement(target, scope = "", mode = "bug-bounty", maxFiles = 2000,
|
|
|
37175
37515
|
};
|
|
37176
37516
|
const isPath = (() => {
|
|
37177
37517
|
try {
|
|
37178
|
-
return
|
|
37518
|
+
return existsSync9(target) && (statSync3(target).isDirectory() || statSync3(target).isFile());
|
|
37179
37519
|
} catch {
|
|
37180
37520
|
return false;
|
|
37181
37521
|
}
|
|
@@ -37833,8 +38173,8 @@ var CHAIN_ID_TO_ESCALATION = {
|
|
|
37833
38173
|
};
|
|
37834
38174
|
function loadChainLinks() {
|
|
37835
38175
|
try {
|
|
37836
|
-
const dir =
|
|
37837
|
-
const data = JSON.parse(
|
|
38176
|
+
const dir = join15(fileURLToPath9(new URL(".", import.meta.url)), "..");
|
|
38177
|
+
const data = JSON.parse(readFileSync14(join15(dir, "intelligence", "chain_links.json"), "utf8"));
|
|
37838
38178
|
return data.links ?? [];
|
|
37839
38179
|
} catch {
|
|
37840
38180
|
return [];
|
|
@@ -37990,18 +38330,18 @@ function compactState(phase, findings) {
|
|
|
37990
38330
|
}
|
|
37991
38331
|
|
|
37992
38332
|
// src/tasks.ts
|
|
37993
|
-
import { mkdirSync as mkdirSync6, readFileSync as
|
|
37994
|
-
import { join as
|
|
37995
|
-
import { fileURLToPath as
|
|
38333
|
+
import { mkdirSync as mkdirSync6, readFileSync as readFileSync15, writeFileSync as writeFileSync3 } from "node:fs";
|
|
38334
|
+
import { join as join16 } from "node:path";
|
|
38335
|
+
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
37996
38336
|
function tasksDir() {
|
|
37997
|
-
return
|
|
38337
|
+
return join16(fileURLToPath10(new URL(".", import.meta.url)), "..", ".blitzstrike", "tasks");
|
|
37998
38338
|
}
|
|
37999
38339
|
function taskPath(id) {
|
|
38000
|
-
return
|
|
38340
|
+
return join16(tasksDir(), `${id}.json`);
|
|
38001
38341
|
}
|
|
38002
38342
|
function load3(id) {
|
|
38003
38343
|
try {
|
|
38004
|
-
return JSON.parse(
|
|
38344
|
+
return JSON.parse(readFileSync15(taskPath(id), "utf8"));
|
|
38005
38345
|
} catch {
|
|
38006
38346
|
return null;
|
|
38007
38347
|
}
|
|
@@ -38341,16 +38681,16 @@ function scaffoldEngagement(target, scope = [], out_of_scope = []) {
|
|
|
38341
38681
|
// src/incremental.ts
|
|
38342
38682
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
38343
38683
|
import { writeFileSync as writeFileSync4, mkdtempSync, rmSync } from "node:fs";
|
|
38344
|
-
import { join as
|
|
38684
|
+
import { join as join17 } from "node:path";
|
|
38345
38685
|
import { tmpdir } from "node:os";
|
|
38346
38686
|
|
|
38347
38687
|
// src/eagle2.ts
|
|
38348
38688
|
var import_php_parser2 = __toESM(require_src(), 1);
|
|
38349
|
-
import { readFileSync as
|
|
38689
|
+
import { readFileSync as readFileSync18 } from "node:fs";
|
|
38350
38690
|
|
|
38351
38691
|
// src/dataflow.ts
|
|
38352
38692
|
init_scanner();
|
|
38353
|
-
import { readFileSync as
|
|
38693
|
+
import { readFileSync as readFileSync16 } from "node:fs";
|
|
38354
38694
|
var SOURCES = {
|
|
38355
38695
|
$_GET: { id: "http_get", label: "HTTP GET parameter", attacker_controlled: true },
|
|
38356
38696
|
$_POST: { id: "http_post", label: "HTTP POST body", attacker_controlled: true },
|
|
@@ -38435,7 +38775,7 @@ function traceDataFlow(path) {
|
|
|
38435
38775
|
return result;
|
|
38436
38776
|
let text;
|
|
38437
38777
|
try {
|
|
38438
|
-
text =
|
|
38778
|
+
text = readFileSync16(path, "utf8");
|
|
38439
38779
|
} catch {
|
|
38440
38780
|
return result;
|
|
38441
38781
|
}
|
|
@@ -38516,7 +38856,7 @@ init_scanner();
|
|
|
38516
38856
|
|
|
38517
38857
|
// src/callgraph.ts
|
|
38518
38858
|
var import_php_parser = __toESM(require_src(), 1);
|
|
38519
|
-
import { readFileSync as
|
|
38859
|
+
import { readFileSync as readFileSync17 } from "node:fs";
|
|
38520
38860
|
var parser = new import_php_parser.Engine({
|
|
38521
38861
|
parser: { extractDoc: false, php7: true },
|
|
38522
38862
|
ast: { withPositions: true, withSource: false }
|
|
@@ -38577,7 +38917,7 @@ function buildCallGraph(path) {
|
|
|
38577
38917
|
const g = { nodes: new Map, edges: [] };
|
|
38578
38918
|
let code;
|
|
38579
38919
|
try {
|
|
38580
|
-
code =
|
|
38920
|
+
code = readFileSync17(path, "utf8");
|
|
38581
38921
|
} catch {
|
|
38582
38922
|
return g;
|
|
38583
38923
|
}
|
|
@@ -39239,7 +39579,7 @@ function resolveFuncId(name, summaries) {
|
|
|
39239
39579
|
function analyzeDataFlow2(path) {
|
|
39240
39580
|
let cacheCode = "";
|
|
39241
39581
|
try {
|
|
39242
|
-
cacheCode =
|
|
39582
|
+
cacheCode = readFileSync18(path, "utf8");
|
|
39243
39583
|
} catch {}
|
|
39244
39584
|
if (cacheCode) {
|
|
39245
39585
|
const cached = getCache("eagle2", cacheCode);
|
|
@@ -39261,7 +39601,7 @@ function analyzeDataFlow2(path) {
|
|
|
39261
39601
|
};
|
|
39262
39602
|
let code;
|
|
39263
39603
|
try {
|
|
39264
|
-
code = cacheCode ||
|
|
39604
|
+
code = cacheCode || readFileSync18(path, "utf8");
|
|
39265
39605
|
} catch {
|
|
39266
39606
|
return result;
|
|
39267
39607
|
}
|
|
@@ -57947,8 +58287,8 @@ function analyzeChangedFiles(repo, base = "HEAD~1", head = "HEAD") {
|
|
|
57947
58287
|
continue;
|
|
57948
58288
|
const lang = detectLanguage(file)?.language;
|
|
57949
58289
|
if (lang === "php") {
|
|
57950
|
-
const dir = mkdtempSync(
|
|
57951
|
-
const tmp =
|
|
58290
|
+
const dir = mkdtempSync(join17(tmpdir(), "blitz-incr-"));
|
|
58291
|
+
const tmp = join17(dir, "changed.php");
|
|
57952
58292
|
writeFileSync4(tmp, code);
|
|
57953
58293
|
try {
|
|
57954
58294
|
const r = analyzeDataFlow2(tmp);
|
|
@@ -57969,7 +58309,7 @@ function analyzeChangedFiles(repo, base = "HEAD~1", head = "HEAD") {
|
|
|
57969
58309
|
// src/taint.ts
|
|
57970
58310
|
init_scanner();
|
|
57971
58311
|
var import_php_parser4 = __toESM(require_src(), 1);
|
|
57972
|
-
import { readFileSync as
|
|
58312
|
+
import { readFileSync as readFileSync19 } from "node:fs";
|
|
57973
58313
|
var parser4 = new import_php_parser4.Engine({
|
|
57974
58314
|
parser: { extractDoc: false, php7: true },
|
|
57975
58315
|
ast: { withPositions: true, withSource: false }
|
|
@@ -58267,7 +58607,7 @@ function analyzeTaint(path) {
|
|
|
58267
58607
|
const result = { file: path, findings: [], suppressed: 0 };
|
|
58268
58608
|
let code;
|
|
58269
58609
|
try {
|
|
58270
|
-
code =
|
|
58610
|
+
code = readFileSync19(path, "utf8");
|
|
58271
58611
|
} catch {
|
|
58272
58612
|
return result;
|
|
58273
58613
|
}
|
|
@@ -58361,15 +58701,15 @@ function taintTree(root, maxFiles = 2000) {
|
|
|
58361
58701
|
}
|
|
58362
58702
|
|
|
58363
58703
|
// src/differential.ts
|
|
58364
|
-
import { writeFileSync as writeFileSync5, rmSync as rmSync2, mkdtempSync as mkdtempSync2, readFileSync as
|
|
58365
|
-
import { join as
|
|
58704
|
+
import { writeFileSync as writeFileSync5, rmSync as rmSync2, mkdtempSync as mkdtempSync2, readFileSync as readFileSync20 } from "node:fs";
|
|
58705
|
+
import { join as join18 } from "node:path";
|
|
58366
58706
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
58367
58707
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
58368
58708
|
init_scanner();
|
|
58369
58709
|
function runEngine(code, language, file) {
|
|
58370
58710
|
if (language === "php") {
|
|
58371
|
-
const dir = mkdtempSync2(
|
|
58372
|
-
const tmp =
|
|
58711
|
+
const dir = mkdtempSync2(join18(tmpdir2(), "blitz-diff-"));
|
|
58712
|
+
const tmp = join18(dir, "old.php");
|
|
58373
58713
|
writeFileSync5(tmp, code);
|
|
58374
58714
|
try {
|
|
58375
58715
|
const r = analyzeDataFlow2(tmp);
|
|
@@ -58523,8 +58863,8 @@ function languageOf(file) {
|
|
|
58523
58863
|
return adapter?.language ?? "php";
|
|
58524
58864
|
}
|
|
58525
58865
|
function analyzeDifferentialFiles(oldPath, newPath, language) {
|
|
58526
|
-
const oldCode =
|
|
58527
|
-
const newCode =
|
|
58866
|
+
const oldCode = readFileSync20(oldPath, "utf8");
|
|
58867
|
+
const newCode = readFileSync20(newPath, "utf8");
|
|
58528
58868
|
const lang = language ?? languageOf(newPath);
|
|
58529
58869
|
return analyzeDifferential(oldCode, newCode, lang, newPath);
|
|
58530
58870
|
}
|
|
@@ -58651,28 +58991,28 @@ function analyzePatch(oldCode, newCode, language = "php") {
|
|
|
58651
58991
|
};
|
|
58652
58992
|
}
|
|
58653
58993
|
function analyzePatchFiles(oldPath, newPath, language) {
|
|
58654
|
-
const oldCode =
|
|
58655
|
-
const newCode =
|
|
58994
|
+
const oldCode = readFileSync20(oldPath, "utf8");
|
|
58995
|
+
const newCode = readFileSync20(newPath, "utf8");
|
|
58656
58996
|
const lang = language ?? languageOf(newPath);
|
|
58657
58997
|
return analyzePatch(oldCode, newCode, lang);
|
|
58658
58998
|
}
|
|
58659
58999
|
|
|
58660
59000
|
// src/frameworks.ts
|
|
58661
|
-
import { readFileSync as
|
|
58662
|
-
import { join as
|
|
58663
|
-
import { fileURLToPath as
|
|
58664
|
-
var
|
|
58665
|
-
var INTEL2 =
|
|
58666
|
-
var
|
|
59001
|
+
import { readFileSync as readFileSync21, existsSync as existsSync10 } from "node:fs";
|
|
59002
|
+
import { join as join19 } from "node:path";
|
|
59003
|
+
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
59004
|
+
var ROOT7 = join19(fileURLToPath11(new URL(".", import.meta.url)), "..");
|
|
59005
|
+
var INTEL2 = join19(ROOT7, "intelligence");
|
|
59006
|
+
var cache2 = null;
|
|
58667
59007
|
function load4() {
|
|
58668
|
-
if (
|
|
58669
|
-
return
|
|
58670
|
-
const p =
|
|
58671
|
-
if (!
|
|
59008
|
+
if (cache2)
|
|
59009
|
+
return cache2;
|
|
59010
|
+
const p = join19(INTEL2, "frameworks.json");
|
|
59011
|
+
if (!existsSync10(p))
|
|
58672
59012
|
return null;
|
|
58673
59013
|
try {
|
|
58674
|
-
|
|
58675
|
-
return
|
|
59014
|
+
cache2 = JSON.parse(readFileSync21(p, "utf8"));
|
|
59015
|
+
return cache2;
|
|
58676
59016
|
} catch {
|
|
58677
59017
|
return null;
|
|
58678
59018
|
}
|
|
@@ -59182,8 +59522,8 @@ function nextSteps(ctx) {
|
|
|
59182
59522
|
// src/git-history.ts
|
|
59183
59523
|
init_complex_bugs();
|
|
59184
59524
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
59185
|
-
import { existsSync as
|
|
59186
|
-
import { join as
|
|
59525
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
59526
|
+
import { join as join20 } from "node:path";
|
|
59187
59527
|
function parseDeletions(output) {
|
|
59188
59528
|
const out = [];
|
|
59189
59529
|
let commit = "";
|
|
@@ -59212,7 +59552,7 @@ function blobBeforeDeletion(root, commit, path) {
|
|
|
59212
59552
|
function scanGitHistory(root, opts) {
|
|
59213
59553
|
const limit = opts?.limit ?? 30;
|
|
59214
59554
|
const findings = [];
|
|
59215
|
-
if (!
|
|
59555
|
+
if (!existsSync12(join20(root, ".git"))) {
|
|
59216
59556
|
return { root, is_git_repo: false, total: 0, findings: [], error: "not a git repository (no .git dir)" };
|
|
59217
59557
|
}
|
|
59218
59558
|
if (opts?.secretPattern) {
|
|
@@ -59359,13 +59699,13 @@ async function validateLeakedKey(input) {
|
|
|
59359
59699
|
}
|
|
59360
59700
|
|
|
59361
59701
|
// src/hackbot-arena.ts
|
|
59362
|
-
import { readFileSync as
|
|
59363
|
-
import { join as
|
|
59364
|
-
import { fileURLToPath as
|
|
59365
|
-
var __dirname3 = dirname3(
|
|
59702
|
+
import { readFileSync as readFileSync22 } from "node:fs";
|
|
59703
|
+
import { join as join21, dirname as dirname3 } from "node:path";
|
|
59704
|
+
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
59705
|
+
var __dirname3 = dirname3(fileURLToPath12(import.meta.url));
|
|
59366
59706
|
function load5() {
|
|
59367
59707
|
try {
|
|
59368
|
-
return JSON.parse(
|
|
59708
|
+
return JSON.parse(readFileSync22(join21(__dirname3, "..", "intelligence", "hackbot-arena.json"), "utf8"));
|
|
59369
59709
|
} catch {
|
|
59370
59710
|
return { total: 0, flag_format: "FLAG{nusasec-<32 hex>}", labs: [] };
|
|
59371
59711
|
}
|
|
@@ -59529,13 +59869,13 @@ function listSeverityMap() {
|
|
|
59529
59869
|
}
|
|
59530
59870
|
|
|
59531
59871
|
// src/datarefresh.ts
|
|
59532
|
-
import { readFileSync as
|
|
59533
|
-
import { join as
|
|
59534
|
-
import { fileURLToPath as
|
|
59535
|
-
var __dirname4 = dirname4(
|
|
59872
|
+
import { readFileSync as readFileSync23 } from "node:fs";
|
|
59873
|
+
import { join as join22, dirname as dirname4 } from "node:path";
|
|
59874
|
+
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
59875
|
+
var __dirname4 = dirname4(fileURLToPath13(import.meta.url));
|
|
59536
59876
|
function loadJson2(rel) {
|
|
59537
59877
|
try {
|
|
59538
|
-
return JSON.parse(
|
|
59878
|
+
return JSON.parse(readFileSync23(join22(__dirname4, "..", rel), "utf8"));
|
|
59539
59879
|
} catch {
|
|
59540
59880
|
return null;
|
|
59541
59881
|
}
|
|
@@ -59727,18 +60067,18 @@ async function brokenLinkScan(url, maxHosts = 30) {
|
|
|
59727
60067
|
}
|
|
59728
60068
|
|
|
59729
60069
|
// src/benchmark.ts
|
|
59730
|
-
import { readFileSync as
|
|
59731
|
-
import { join as
|
|
59732
|
-
import { fileURLToPath as
|
|
59733
|
-
import { tmpdir as tmpdir3, homedir as
|
|
60070
|
+
import { readFileSync as readFileSync25, readdirSync as readdirSync6, writeFileSync as writeFileSync6, rmSync as rmSync3, mkdirSync as mkdirSync7 } from "node:fs";
|
|
60071
|
+
import { join as join24 } from "node:path";
|
|
60072
|
+
import { fileURLToPath as fileURLToPath15 } from "node:url";
|
|
60073
|
+
import { tmpdir as tmpdir3, homedir as homedir9 } from "node:os";
|
|
59734
60074
|
init_complex_bugs();
|
|
59735
|
-
var
|
|
59736
|
-
var CORPUS =
|
|
59737
|
-
var CAPTURED_CORPUS_DIR = process.env.BLITZSTRIKE_CORPUS_DIR ??
|
|
60075
|
+
var ROOT8 = join24(fileURLToPath15(new URL(".", import.meta.url)), "..");
|
|
60076
|
+
var CORPUS = join24(ROOT8, "bench", "corpus");
|
|
60077
|
+
var CAPTURED_CORPUS_DIR = process.env.BLITZSTRIKE_CORPUS_DIR ?? join24(homedir9(), ".blitzstrike", "corpus");
|
|
59738
60078
|
function parseCorpusFile(path) {
|
|
59739
60079
|
let text;
|
|
59740
60080
|
try {
|
|
59741
|
-
text =
|
|
60081
|
+
text = readFileSync25(path, "utf8");
|
|
59742
60082
|
} catch {
|
|
59743
60083
|
return null;
|
|
59744
60084
|
}
|
|
@@ -59791,17 +60131,17 @@ function parseCorpusFile(path) {
|
|
|
59791
60131
|
function loadDir(dir) {
|
|
59792
60132
|
const entries = [];
|
|
59793
60133
|
try {
|
|
59794
|
-
for (const f of
|
|
60134
|
+
for (const f of readdirSync6(dir)) {
|
|
59795
60135
|
if (!f.endsWith(".md"))
|
|
59796
60136
|
continue;
|
|
59797
|
-
const e = parseCorpusFile(
|
|
60137
|
+
const e = parseCorpusFile(join24(dir, f));
|
|
59798
60138
|
if (e)
|
|
59799
60139
|
entries.push(e);
|
|
59800
60140
|
}
|
|
59801
60141
|
} catch {}
|
|
59802
60142
|
return entries;
|
|
59803
60143
|
}
|
|
59804
|
-
function
|
|
60144
|
+
function loadCorpus2() {
|
|
59805
60145
|
return [...loadDir(CORPUS), ...loadDir(CAPTURED_CORPUS_DIR)];
|
|
59806
60146
|
}
|
|
59807
60147
|
function captureFalsePositive(input) {
|
|
@@ -59821,7 +60161,7 @@ function captureFalsePositive(input) {
|
|
|
59821
60161
|
input.code,
|
|
59822
60162
|
"```"
|
|
59823
60163
|
].filter((l) => l !== null);
|
|
59824
|
-
const path =
|
|
60164
|
+
const path = join24(CAPTURED_CORPUS_DIR, `${id}.md`);
|
|
59825
60165
|
writeFileSync6(path, lines.join(`
|
|
59826
60166
|
`) + `
|
|
59827
60167
|
`, "utf8");
|
|
@@ -59843,7 +60183,7 @@ function detect(entry) {
|
|
|
59843
60183
|
}
|
|
59844
60184
|
const lang = entry.language;
|
|
59845
60185
|
if (lang === "php") {
|
|
59846
|
-
const tmp =
|
|
60186
|
+
const tmp = join24(tmpdir3(), `blitzstrike-bench-${entry.id}-${process.pid}.php`);
|
|
59847
60187
|
writeFileSync6(tmp, entry.code);
|
|
59848
60188
|
const r = analyzeDataFlow2(tmp);
|
|
59849
60189
|
rmSync3(tmp, { force: true });
|
|
@@ -59858,7 +60198,7 @@ function detect(entry) {
|
|
|
59858
60198
|
return { detected: false };
|
|
59859
60199
|
}
|
|
59860
60200
|
function runBenchmark() {
|
|
59861
|
-
const entries =
|
|
60201
|
+
const entries = loadCorpus2();
|
|
59862
60202
|
const results = entries.map((entry) => {
|
|
59863
60203
|
const { detected, sinkKind } = detect(entry);
|
|
59864
60204
|
const outcome = entry.vulnerable ? detected ? "tp" : "fn" : detected ? "fp" : "tn";
|
|
@@ -59912,25 +60252,25 @@ function runBenchmark() {
|
|
|
59912
60252
|
}
|
|
59913
60253
|
|
|
59914
60254
|
// src/obligations.ts
|
|
59915
|
-
import { readFileSync as
|
|
59916
|
-
import { join as
|
|
60255
|
+
import { readFileSync as readFileSync26, appendFileSync as appendFileSync4, mkdirSync as mkdirSync8, existsSync as existsSync13, writeFileSync as writeFileSync7 } from "node:fs";
|
|
60256
|
+
import { join as join25 } from "node:path";
|
|
59917
60257
|
import { createHash as createHash6 } from "node:crypto";
|
|
59918
|
-
import { homedir as
|
|
59919
|
-
var HOME_DIR4 = process.env.BLITZSTRIKE_HOME ??
|
|
59920
|
-
var OBLIGATION_PATH =
|
|
60258
|
+
import { homedir as homedir10 } from "node:os";
|
|
60259
|
+
var HOME_DIR4 = process.env.BLITZSTRIKE_HOME ?? join25(homedir10(), ".blitzstrike");
|
|
60260
|
+
var OBLIGATION_PATH = join25(HOME_DIR4, "obligations.jsonl");
|
|
59921
60261
|
function ensureDir3() {
|
|
59922
|
-
if (!
|
|
60262
|
+
if (!existsSync13(HOME_DIR4))
|
|
59923
60263
|
mkdirSync8(HOME_DIR4, { recursive: true });
|
|
59924
60264
|
}
|
|
59925
60265
|
function shortId2(claim) {
|
|
59926
60266
|
return `obl-${createHash6("sha256").update(`${claim}\x00${Date.now()}`).digest("hex").slice(0, 12)}`;
|
|
59927
60267
|
}
|
|
59928
60268
|
function loadObligations() {
|
|
59929
|
-
if (!
|
|
60269
|
+
if (!existsSync13(OBLIGATION_PATH))
|
|
59930
60270
|
return [];
|
|
59931
60271
|
try {
|
|
59932
60272
|
const out = [];
|
|
59933
|
-
for (const line of
|
|
60273
|
+
for (const line of readFileSync26(OBLIGATION_PATH, "utf8").split(`
|
|
59934
60274
|
`)) {
|
|
59935
60275
|
const t = line.trim();
|
|
59936
60276
|
if (!t)
|
|
@@ -60034,11 +60374,11 @@ init_framework_security();
|
|
|
60034
60374
|
// src/variant-scan.ts
|
|
60035
60375
|
init_scanner();
|
|
60036
60376
|
init_complex_bugs();
|
|
60037
|
-
import { readFileSync as
|
|
60377
|
+
import { readFileSync as readFileSync28 } from "node:fs";
|
|
60038
60378
|
|
|
60039
60379
|
// src/cross-file.ts
|
|
60040
60380
|
init_scanner();
|
|
60041
|
-
import { readFileSync as
|
|
60381
|
+
import { readFileSync as readFileSync27 } from "node:fs";
|
|
60042
60382
|
var PUBLIC_HOOK_RE = /(?:wp_ajax_nopriv_\w+|admin_post_nopriv_\w+|init|template_redirect|wp_loaded|parse_request|user_register|um_user_register|register_new_user|authenticate)/;
|
|
60043
60383
|
var PRIV_SINK_RE = /\b(set_role|add_role|remove_role|set_user_role|wp_set_current_user|wp_set_auth_cookie|wp_insert_user|wp_create_user|wp_update_user)\s*\(/;
|
|
60044
60384
|
var ROLE_META_RE = /update_user_meta\s*\(\s*[^,]+,\s*['"](wp_capabilities|role|roles|capabilities|wp_user_level)['"]/;
|
|
@@ -60090,7 +60430,7 @@ function detectCrossFilePrivesc(root) {
|
|
|
60090
60430
|
for (const file of files) {
|
|
60091
60431
|
let code;
|
|
60092
60432
|
try {
|
|
60093
|
-
code = stripComments(
|
|
60433
|
+
code = stripComments(readFileSync27(file, "utf8"));
|
|
60094
60434
|
} catch {
|
|
60095
60435
|
continue;
|
|
60096
60436
|
}
|
|
@@ -60131,7 +60471,7 @@ function detectCrossFilePrivesc(root) {
|
|
|
60131
60471
|
for (const file of files) {
|
|
60132
60472
|
let code;
|
|
60133
60473
|
try {
|
|
60134
|
-
code = stripComments(
|
|
60474
|
+
code = stripComments(readFileSync27(file, "utf8"));
|
|
60135
60475
|
} catch {
|
|
60136
60476
|
continue;
|
|
60137
60477
|
}
|
|
@@ -60154,7 +60494,7 @@ function detectCrossFilePrivesc(root) {
|
|
|
60154
60494
|
for (const file of files) {
|
|
60155
60495
|
let code;
|
|
60156
60496
|
try {
|
|
60157
|
-
code = stripComments(
|
|
60497
|
+
code = stripComments(readFileSync27(file, "utf8"));
|
|
60158
60498
|
} catch {
|
|
60159
60499
|
continue;
|
|
60160
60500
|
}
|
|
@@ -60269,7 +60609,7 @@ function variantScan(root, opts = {}) {
|
|
|
60269
60609
|
for (const file of files) {
|
|
60270
60610
|
let code;
|
|
60271
60611
|
try {
|
|
60272
|
-
code =
|
|
60612
|
+
code = readFileSync28(file, "utf8");
|
|
60273
60613
|
} catch {
|
|
60274
60614
|
continue;
|
|
60275
60615
|
}
|
|
@@ -60933,7 +61273,7 @@ import { spawn as spawn3, execSync as execSync2 } from "node:child_process";
|
|
|
60933
61273
|
import { createServer } from "node:http";
|
|
60934
61274
|
import { randomUUID } from "node:crypto";
|
|
60935
61275
|
import { networkInterfaces } from "node:os";
|
|
60936
|
-
import { existsSync as
|
|
61276
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
60937
61277
|
var sessions = new Map;
|
|
60938
61278
|
function sleep(ms) {
|
|
60939
61279
|
return new Promise((r) => setTimeout(r, ms));
|
|
@@ -60947,7 +61287,7 @@ function findInteractsh() {
|
|
|
60947
61287
|
const home = process.env.HOME ?? "/root";
|
|
60948
61288
|
const candidates = [`${home}/go/bin/interactsh-client`, "/usr/local/bin/interactsh-client", "/usr/bin/interactsh-client"];
|
|
60949
61289
|
for (const c of candidates)
|
|
60950
|
-
if (
|
|
61290
|
+
if (existsSync14(c))
|
|
60951
61291
|
return c;
|
|
60952
61292
|
return null;
|
|
60953
61293
|
}
|
|
@@ -61952,9 +62292,9 @@ function listPocTypes() {
|
|
|
61952
62292
|
|
|
61953
62293
|
// src/foundry-run.ts
|
|
61954
62294
|
import { execSync as execSync3 } from "node:child_process";
|
|
61955
|
-
import { mkdtempSync as mkdtempSync3, mkdirSync as mkdirSync9, writeFileSync as writeFileSync8, rmSync as rmSync4, existsSync as
|
|
62295
|
+
import { mkdtempSync as mkdtempSync3, mkdirSync as mkdirSync9, writeFileSync as writeFileSync8, rmSync as rmSync4, existsSync as existsSync15 } from "node:fs";
|
|
61956
62296
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
61957
|
-
import { join as
|
|
62297
|
+
import { join as join26 } from "node:path";
|
|
61958
62298
|
function findForge() {
|
|
61959
62299
|
try {
|
|
61960
62300
|
const p = execSync3("which forge 2>/dev/null", { encoding: "utf8", timeout: 3000 }).trim();
|
|
@@ -61964,7 +62304,7 @@ function findForge() {
|
|
|
61964
62304
|
const home = process.env.HOME ?? "/root";
|
|
61965
62305
|
const candidates = [`${home}/.foundry/bin/forge`, "/usr/local/bin/forge", "/usr/bin/forge"];
|
|
61966
62306
|
for (const c of candidates)
|
|
61967
|
-
if (
|
|
62307
|
+
if (existsSync15(c))
|
|
61968
62308
|
return c;
|
|
61969
62309
|
return null;
|
|
61970
62310
|
}
|
|
@@ -62003,14 +62343,14 @@ async function foundryRun(input) {
|
|
|
62003
62343
|
};
|
|
62004
62344
|
}
|
|
62005
62345
|
const poc = input.poc_code ?? foundryPoc(input.class_ ?? "missing_access_control", name);
|
|
62006
|
-
const dir = mkdtempSync3(
|
|
62346
|
+
const dir = mkdtempSync3(join26(tmpdir4(), "blitzstrike-foundry-"));
|
|
62007
62347
|
try {
|
|
62008
62348
|
try {
|
|
62009
62349
|
execSync3(`${forge} init --force --no-git ${dir}`, { stdio: "ignore", timeout: 60000 });
|
|
62010
62350
|
} catch {
|
|
62011
|
-
mkdirSync9(
|
|
62012
|
-
mkdirSync9(
|
|
62013
|
-
writeFileSync8(
|
|
62351
|
+
mkdirSync9(join26(dir, "src"), { recursive: true });
|
|
62352
|
+
mkdirSync9(join26(dir, "test"), { recursive: true });
|
|
62353
|
+
writeFileSync8(join26(dir, "foundry.toml"), `[profile.default]
|
|
62014
62354
|
src = "src"
|
|
62015
62355
|
out = "out"
|
|
62016
62356
|
libs = ["lib"]
|
|
@@ -62020,12 +62360,12 @@ solc = "0.8.20"
|
|
|
62020
62360
|
for (const f of ["Counter.sol", "Counter.t.sol", "Counter.s.sol"]) {
|
|
62021
62361
|
for (const sub of ["src", "test", "script"]) {
|
|
62022
62362
|
try {
|
|
62023
|
-
rmSync4(
|
|
62363
|
+
rmSync4(join26(dir, sub, f), { force: true });
|
|
62024
62364
|
} catch {}
|
|
62025
62365
|
}
|
|
62026
62366
|
}
|
|
62027
|
-
writeFileSync8(
|
|
62028
|
-
writeFileSync8(
|
|
62367
|
+
writeFileSync8(join26(dir, "src", `${name}.sol`), input.contract_code);
|
|
62368
|
+
writeFileSync8(join26(dir, "test", `${name}.t.sol`), poc);
|
|
62029
62369
|
const { out } = runForge(forge, dir, input.timeout_ms ?? 60000);
|
|
62030
62370
|
const tests = parseTestResults(out);
|
|
62031
62371
|
const anyFail = tests.some((t) => t.status === "fail");
|
|
@@ -62043,33 +62383,33 @@ solc = "0.8.20"
|
|
|
62043
62383
|
}
|
|
62044
62384
|
|
|
62045
62385
|
// src/enterprise-benchmark.ts
|
|
62046
|
-
import { existsSync as
|
|
62047
|
-
import { join as
|
|
62048
|
-
import { fileURLToPath as
|
|
62386
|
+
import { existsSync as existsSync16, readFileSync as readFileSync29, readdirSync as readdirSync7, statSync as statSync4 } from "node:fs";
|
|
62387
|
+
import { join as join27, resolve } from "node:path";
|
|
62388
|
+
import { fileURLToPath as fileURLToPath16 } from "node:url";
|
|
62049
62389
|
init_complex_bugs();
|
|
62050
|
-
var
|
|
62390
|
+
var ROOT9 = resolve(fileURLToPath16(new URL(".", import.meta.url)), "..", "bench", "enterprise");
|
|
62051
62391
|
var ENTERPRISE_FIXTURES = [
|
|
62052
|
-
{ id: "php-laravel", dir:
|
|
62053
|
-
{ id: "js-express", dir:
|
|
62054
|
-
{ id: "py-django", dir:
|
|
62055
|
-
{ id: "java-spring", dir:
|
|
62056
|
-
{ id: "wp-batch-route", dir:
|
|
62057
|
-
{ id: "php-complex", dir:
|
|
62392
|
+
{ id: "php-laravel", dir: join27(ROOT9, "php-laravel"), expected_vulns: 4 },
|
|
62393
|
+
{ id: "js-express", dir: join27(ROOT9, "js-express"), expected_vulns: 2 },
|
|
62394
|
+
{ id: "py-django", dir: join27(ROOT9, "py-django"), expected_vulns: 2 },
|
|
62395
|
+
{ id: "java-spring", dir: join27(ROOT9, "java-spring"), expected_vulns: 2 },
|
|
62396
|
+
{ id: "wp-batch-route", dir: join27(ROOT9, "wp-batch-route"), expected_vulns: 3 },
|
|
62397
|
+
{ id: "php-complex", dir: join27(ROOT9, "php-complex"), expected_vulns: 4 }
|
|
62058
62398
|
];
|
|
62059
62399
|
function sourceFiles(root) {
|
|
62060
62400
|
const out = [];
|
|
62061
62401
|
const walk = (dir) => {
|
|
62062
62402
|
let entries;
|
|
62063
62403
|
try {
|
|
62064
|
-
entries =
|
|
62404
|
+
entries = readdirSync7(dir);
|
|
62065
62405
|
} catch {
|
|
62066
62406
|
return;
|
|
62067
62407
|
}
|
|
62068
62408
|
for (const e of entries) {
|
|
62069
|
-
const p =
|
|
62409
|
+
const p = join27(dir, e);
|
|
62070
62410
|
let st;
|
|
62071
62411
|
try {
|
|
62072
|
-
st =
|
|
62412
|
+
st = statSync4(p);
|
|
62073
62413
|
} catch {
|
|
62074
62414
|
continue;
|
|
62075
62415
|
}
|
|
@@ -62087,7 +62427,7 @@ function detectFixture(dir) {
|
|
|
62087
62427
|
for (const f of sourceFiles(dir)) {
|
|
62088
62428
|
let code;
|
|
62089
62429
|
try {
|
|
62090
|
-
code =
|
|
62430
|
+
code = readFileSync29(f, "utf8");
|
|
62091
62431
|
} catch {
|
|
62092
62432
|
continue;
|
|
62093
62433
|
}
|
|
@@ -62105,7 +62445,7 @@ function detectFixture(dir) {
|
|
|
62105
62445
|
function runEnterpriseBenchmark() {
|
|
62106
62446
|
const fixtures = [];
|
|
62107
62447
|
for (const fx of ENTERPRISE_FIXTURES) {
|
|
62108
|
-
if (!
|
|
62448
|
+
if (!existsSync16(fx.dir)) {
|
|
62109
62449
|
fixtures.push({ id: fx.id, available: false, detected: 0, expected: fx.expected_vulns, recall: 0 });
|
|
62110
62450
|
continue;
|
|
62111
62451
|
}
|
|
@@ -63191,7 +63531,7 @@ ${statusLine}` : statusLine },
|
|
|
63191
63531
|
let src = code;
|
|
63192
63532
|
if (!src && path) {
|
|
63193
63533
|
try {
|
|
63194
|
-
src =
|
|
63534
|
+
src = readFileSync31(path, "utf8");
|
|
63195
63535
|
} catch {
|
|
63196
63536
|
return { content: [{ type: "text", text: JSON.stringify({ error: "unreadable path" }) }] };
|
|
63197
63537
|
}
|
|
@@ -63272,7 +63612,7 @@ ${statusLine}` : statusLine },
|
|
|
63272
63612
|
let src = code;
|
|
63273
63613
|
if (!src && path) {
|
|
63274
63614
|
try {
|
|
63275
|
-
src =
|
|
63615
|
+
src = readFileSync31(path, "utf8");
|
|
63276
63616
|
} catch {
|
|
63277
63617
|
return { content: [{ type: "text", text: JSON.stringify({ error: "unreadable path" }) }] };
|
|
63278
63618
|
}
|
|
@@ -63354,6 +63694,27 @@ ${statusLine}` : statusLine },
|
|
|
63354
63694
|
}, async ({ hint }) => {
|
|
63355
63695
|
return { content: [{ type: "text", text: JSON.stringify(surfaceMap(hint ?? "")) }] };
|
|
63356
63696
|
});
|
|
63697
|
+
server.registerTool("sync_cve_corpus", {
|
|
63698
|
+
title: "Refresh the CVE fingerprint corpus from nuclei-templates",
|
|
63699
|
+
description: "Auto-refresh the CVE watchlist corpus: run `nuclei -update-templates` (best-effort, if nuclei is installed), then reload the corpus directly from the live nuclei-templates `http/cves/**` tree. The CVE corpus is read LIVE from nuclei-templates whenever it is present on disk, so it auto-stays current after a template update; this tool forces a refresh and reports the fresh count + whether the source is live or the bundled snapshot. Call it before a large recon pass to pick up newly-disclosed CVEs.",
|
|
63700
|
+
inputSchema: {}
|
|
63701
|
+
}, async () => {
|
|
63702
|
+
let update = "skipped (nuclei not found)";
|
|
63703
|
+
try {
|
|
63704
|
+
execFileSync6("nuclei", ["-update-templates"], { timeout: 120000, stdio: "pipe" });
|
|
63705
|
+
update = "ok";
|
|
63706
|
+
} catch {}
|
|
63707
|
+
invalidateCorpusCache();
|
|
63708
|
+
const corpus = loadCorpusEntries();
|
|
63709
|
+
return {
|
|
63710
|
+
content: [
|
|
63711
|
+
{
|
|
63712
|
+
type: "text",
|
|
63713
|
+
text: JSON.stringify({ nuclei_update: update, source: corpusSourceIsLive() ? "live nuclei-templates" : "bundled snapshot", cve_count: corpus.length })
|
|
63714
|
+
}
|
|
63715
|
+
]
|
|
63716
|
+
};
|
|
63717
|
+
});
|
|
63357
63718
|
server.registerTool("auto_poc", {
|
|
63358
63719
|
title: "Auto-PoC — generate a copy-paste-ready reproduction recipe",
|
|
63359
63720
|
description: "Turn a finding into a concrete reproduction recipe (the 'reproducible' gate question made executable). Given a vuln class + target + endpoint + param, emit the exact request (with a MARKER), a NEGATIVE CONTROL, and the expected differential that PROVES the bug — plus a Patchstack-style title, derived severity, and the fix. Covers sql_injection, missing_authz/idor, ssrf, xss, ssti, command_injection, file_upload, mass_assignment, jwt_alg_confusion, crlf, open_redirect, xxe, prototype_pollution, deserialization, hardcoded_secret, cache_deception, cors_misconfiguration, subdomain_takeover. Pass type='list' to enumerate supported classes.",
|
|
@@ -63973,7 +64334,7 @@ ${statusLine}` : statusLine },
|
|
|
63973
64334
|
description: "Route confusion (separate class from source→sink taint): detect attacker-controlled dispatch (call_user_func/forward/dispatch), dynamic method calls ($obj->$m()), dynamic include (LFI), batch/proxy forwarding without per-route auth re-check, and route matching without path normalization.",
|
|
63974
64335
|
inputSchema: { path: string2().describe("Source file path (PHP)") }
|
|
63975
64336
|
}, async ({ path }) => {
|
|
63976
|
-
const code =
|
|
64337
|
+
const code = readFileSync31(path, "utf8");
|
|
63977
64338
|
const findings = detectRouteConfusion(code, path);
|
|
63978
64339
|
return {
|
|
63979
64340
|
content: [{
|
|
@@ -63987,7 +64348,7 @@ ${statusLine}` : statusLine },
|
|
|
63987
64348
|
description: "Complex-bug detection beyond taint: deserialization→POP gadget chain (unserialize + magic method), type juggling (loose ==/!= vs hash/secret), mass assignment (extract/parse_str without a safe flag), prototype pollution (unsafe merge of request data), CRLF/header injection (user input into a header), path confusion (user input into a file path without canonicalization), SSRF (user-controlled URL with no host allowlist), XXE (user XML parsed without disabling entities), SSTI (user input into a template render with no sandbox), wrong-context sanitization (sanitize_text_field() into a SQL query), missing authorization/nonce on WordPress entry points (wp_ajax_* / admin_post_* / register_rest_route without current_user_can, nonce verification, or permission_callback), CORS misconfiguration (reflected/wildcard origin + credentials), XSS (user input into a DOM sink: innerHTML / dangerouslySetInnerHTML / document.write / .html / eval), and subdomain takeover (CNAME/AliasTarget to a claimable service).",
|
|
63988
64349
|
inputSchema: { path: string2().describe("Source file path") }
|
|
63989
64350
|
}, async ({ path }) => {
|
|
63990
|
-
const code =
|
|
64351
|
+
const code = readFileSync31(path, "utf8");
|
|
63991
64352
|
const findings = detectComplexBugs(code, path);
|
|
63992
64353
|
return {
|
|
63993
64354
|
content: [{
|
|
@@ -64073,7 +64434,7 @@ ${statusLine}` : statusLine },
|
|
|
64073
64434
|
let lang = language;
|
|
64074
64435
|
if (path && !code) {
|
|
64075
64436
|
try {
|
|
64076
|
-
src =
|
|
64437
|
+
src = readFileSync31(path, "utf8");
|
|
64077
64438
|
} catch {
|
|
64078
64439
|
return { content: [{ type: "text", text: JSON.stringify({ error: `cannot read ${path}` }) }] };
|
|
64079
64440
|
}
|
|
@@ -64322,15 +64683,15 @@ async function serve() {
|
|
|
64322
64683
|
|
|
64323
64684
|
// src/index.ts
|
|
64324
64685
|
init_cli();
|
|
64325
|
-
import { readFileSync as
|
|
64326
|
-
import { join as
|
|
64327
|
-
import { fileURLToPath as
|
|
64328
|
-
var
|
|
64686
|
+
import { readFileSync as readFileSync35, existsSync as existsSync19 } from "node:fs";
|
|
64687
|
+
import { join as join32 } from "node:path";
|
|
64688
|
+
import { fileURLToPath as fileURLToPath21 } from "node:url";
|
|
64689
|
+
var ROOT14 = join32(fileURLToPath21(new URL(".", import.meta.url)), "..");
|
|
64329
64690
|
function readVersion() {
|
|
64330
64691
|
try {
|
|
64331
|
-
const p =
|
|
64332
|
-
if (
|
|
64333
|
-
return JSON.parse(
|
|
64692
|
+
const p = join32(ROOT14, "package.json");
|
|
64693
|
+
if (existsSync19(p))
|
|
64694
|
+
return JSON.parse(readFileSync35(p, "utf8")).version ?? "1.0.0";
|
|
64334
64695
|
} catch {}
|
|
64335
64696
|
return "1.0.0";
|
|
64336
64697
|
}
|