blitzstrike 2.4.112 → 2.4.114
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 +26 -0
- package/dist/index.js +602 -242
- package/intelligence/cve-corpus.json +1 -190
- 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,354 @@ 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
|
+
var BRAND_GUARD = [
|
|
36493
|
+
"argus",
|
|
36494
|
+
"wordfence",
|
|
36495
|
+
"hexstrike",
|
|
36496
|
+
"0x4m4",
|
|
36497
|
+
"claude-bughunter",
|
|
36498
|
+
"elementalsouls",
|
|
36499
|
+
"wpcf7",
|
|
36500
|
+
"contact form 7",
|
|
36501
|
+
"elfinder",
|
|
36502
|
+
"ultimate-member",
|
|
36503
|
+
"ultimate member",
|
|
36504
|
+
"forminator",
|
|
36505
|
+
"ai1wm",
|
|
36506
|
+
"all-in-one wp migration",
|
|
36507
|
+
"all in one wp migration",
|
|
36508
|
+
"revslider",
|
|
36509
|
+
"revolution slider",
|
|
36510
|
+
"awarexone",
|
|
36511
|
+
"agentic-bug-hunter",
|
|
36512
|
+
"bugbounty-lab101",
|
|
36513
|
+
"devcop95",
|
|
36514
|
+
"omop",
|
|
36515
|
+
"deve101"
|
|
36516
|
+
];
|
|
36517
|
+
function isBrandGuarded(text) {
|
|
36518
|
+
const t = text.toLowerCase();
|
|
36519
|
+
return BRAND_GUARD.some((b) => t.includes(b));
|
|
36520
|
+
}
|
|
36521
|
+
function tokens(text) {
|
|
36522
|
+
const out = [];
|
|
36523
|
+
for (const t of text.toLowerCase().split(/[^a-z0-9]+/)) {
|
|
36524
|
+
if (!t || t.length < 3)
|
|
36525
|
+
continue;
|
|
36526
|
+
if (/^\d+(\.\d+)*$/.test(t))
|
|
36527
|
+
continue;
|
|
36528
|
+
if (GENERIC.has(t))
|
|
36529
|
+
continue;
|
|
36530
|
+
out.push(t);
|
|
36531
|
+
}
|
|
36532
|
+
return out;
|
|
36533
|
+
}
|
|
36534
|
+
function firstMatch(txt, re) {
|
|
36535
|
+
const m = re.exec(txt);
|
|
36536
|
+
return m ? m[1].trim() : null;
|
|
36537
|
+
}
|
|
36538
|
+
function parseTemplate(text) {
|
|
36539
|
+
const cve = firstMatch(text, /^id:\s*(\S+)/m);
|
|
36540
|
+
if (!cve || !cve.toUpperCase().startsWith("CVE-"))
|
|
36541
|
+
return null;
|
|
36542
|
+
const name = firstMatch(text, /^\s*name:\s*(.+)$/m) ?? cve;
|
|
36543
|
+
const severity = firstMatch(text, /^\s*severity:\s*(\w+)/m) ?? undefined;
|
|
36544
|
+
const epssStr = firstMatch(text, /^\s*epss-score:\s*([\d.]+)/m);
|
|
36545
|
+
const cwe = firstMatch(text, /^\s*cwe-id:\s*(CWE-\d+)/m) ?? undefined;
|
|
36546
|
+
let prod = name.split(/\s+-\s+|:\s+/, 1)[0].trim();
|
|
36547
|
+
prod = prod.replace(/[\s<>=~]+[vV]?[\d][\w.\-]*.*$/, "").trim();
|
|
36548
|
+
if (isBrandGuarded(`${name} ${prod}`))
|
|
36549
|
+
return null;
|
|
36550
|
+
const kw = new Set(tokens(prod));
|
|
36551
|
+
for (const q of text.matchAll(/^\s*(?:fofa|shodan)-query:\s*(.+)$/gm)) {
|
|
36552
|
+
for (const m of q[1].matchAll(/(?:body|title|header|http\.html|html)\s*=\s*"([^"]+)"/g)) {
|
|
36553
|
+
for (const t of tokens(m[1]))
|
|
36554
|
+
kw.add(t);
|
|
36555
|
+
}
|
|
36556
|
+
}
|
|
36557
|
+
if (kw.size === 0)
|
|
36558
|
+
for (const t of tokens(name).slice(0, 3))
|
|
36559
|
+
kw.add(t);
|
|
36560
|
+
const kwSorted = [...kw].sort().slice(0, 8);
|
|
36561
|
+
const match = kwSorted.length ? `\\b(?:${kwSorted.map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})\\b` : undefined;
|
|
36562
|
+
return {
|
|
36563
|
+
cve,
|
|
36564
|
+
name,
|
|
36565
|
+
product: prod,
|
|
36566
|
+
severity,
|
|
36567
|
+
epss: parseFloat(epssStr ?? "0") || 0,
|
|
36568
|
+
cwe,
|
|
36569
|
+
match
|
|
36570
|
+
};
|
|
36571
|
+
}
|
|
36572
|
+
function findTemplatesDir() {
|
|
36573
|
+
const candidates = [join12(homedir8(), "nuclei-templates"), join12(homedir8(), ".nuclei-templates"), "/root/nuclei-templates"];
|
|
36574
|
+
for (const c of candidates)
|
|
36575
|
+
if (existsSync8(join12(c, "http", "cves")))
|
|
36576
|
+
return c;
|
|
36577
|
+
return null;
|
|
36578
|
+
}
|
|
36579
|
+
function loadLiveCorpus() {
|
|
36580
|
+
const dir = findTemplatesDir();
|
|
36581
|
+
if (!dir)
|
|
36582
|
+
return [];
|
|
36583
|
+
const out = [];
|
|
36584
|
+
const walk = (d) => {
|
|
36585
|
+
let entries;
|
|
36586
|
+
try {
|
|
36587
|
+
entries = readdirSync5(d);
|
|
36588
|
+
} catch {
|
|
36589
|
+
return;
|
|
36590
|
+
}
|
|
36591
|
+
for (const name of entries) {
|
|
36592
|
+
const full = join12(d, name);
|
|
36593
|
+
let st;
|
|
36594
|
+
try {
|
|
36595
|
+
st = statSync2(full);
|
|
36596
|
+
} catch {
|
|
36597
|
+
continue;
|
|
36598
|
+
}
|
|
36599
|
+
if (st.isDirectory())
|
|
36600
|
+
walk(full);
|
|
36601
|
+
else if (name.endsWith(".yaml")) {
|
|
36602
|
+
try {
|
|
36603
|
+
const e = parseTemplate(readFileSync11(full, "utf8"));
|
|
36604
|
+
if (e)
|
|
36605
|
+
out.push(e);
|
|
36606
|
+
} catch {}
|
|
36607
|
+
}
|
|
36608
|
+
}
|
|
36609
|
+
};
|
|
36610
|
+
walk(join12(dir, "http", "cves"));
|
|
36611
|
+
return out;
|
|
36612
|
+
}
|
|
36613
|
+
var cache = null;
|
|
36614
|
+
function invalidateCorpusCache() {
|
|
36615
|
+
cache = null;
|
|
36616
|
+
}
|
|
36617
|
+
function loadCorpusEntries() {
|
|
36618
|
+
if (cache)
|
|
36619
|
+
return cache;
|
|
36620
|
+
const live = loadLiveCorpus();
|
|
36621
|
+
if (live.length > 0) {
|
|
36622
|
+
cache = live;
|
|
36623
|
+
return live;
|
|
36624
|
+
}
|
|
36625
|
+
try {
|
|
36626
|
+
const data = JSON.parse(readFileSync11(join12(ROOT4, "intelligence", "cve-corpus.json"), "utf8"));
|
|
36627
|
+
cache = (data.cves ?? []).map((c) => ({
|
|
36628
|
+
cve: String(c.cve ?? ""),
|
|
36629
|
+
name: String(c.name ?? ""),
|
|
36630
|
+
product: String(c.product ?? ""),
|
|
36631
|
+
severity: typeof c.severity === "string" ? c.severity : undefined,
|
|
36632
|
+
epss: typeof c.epss === "number" ? c.epss : parseFloat(String(c.epss ?? "0")) || 0,
|
|
36633
|
+
cwe: typeof c.cwe === "string" ? c.cwe : undefined,
|
|
36634
|
+
match: typeof c.match === "string" ? c.match : undefined
|
|
36635
|
+
}));
|
|
36636
|
+
return cache;
|
|
36637
|
+
} catch {
|
|
36638
|
+
return [];
|
|
36639
|
+
}
|
|
36640
|
+
}
|
|
36641
|
+
function corpusSourceIsLive() {
|
|
36642
|
+
return findTemplatesDir() !== null;
|
|
36643
|
+
}
|
|
36644
|
+
|
|
36645
|
+
// src/hunting-intel.ts
|
|
36646
|
+
var ROOT5 = join13(fileURLToPath7(new URL(".", import.meta.url)), "..");
|
|
36302
36647
|
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
36648
|
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
36649
|
function isValidHostname(host) {
|
|
@@ -36372,30 +36717,24 @@ async function resolveCheck(host) {
|
|
|
36372
36717
|
};
|
|
36373
36718
|
}
|
|
36374
36719
|
function loadWatchlist() {
|
|
36375
|
-
const raw =
|
|
36720
|
+
const raw = readFileSync12(join13(ROOT5, "intelligence", "watchlist.json"), "utf8");
|
|
36376
36721
|
const data = JSON.parse(raw);
|
|
36377
36722
|
return { cwe_frequency: data.cwe_frequency ?? [], cve_watchlist: data.cve_watchlist ?? [] };
|
|
36378
36723
|
}
|
|
36379
36724
|
function loadCorpus() {
|
|
36380
|
-
|
|
36381
|
-
|
|
36382
|
-
|
|
36383
|
-
|
|
36384
|
-
|
|
36385
|
-
|
|
36386
|
-
|
|
36387
|
-
|
|
36388
|
-
|
|
36389
|
-
|
|
36390
|
-
|
|
36391
|
-
|
|
36392
|
-
|
|
36393
|
-
version_key: null,
|
|
36394
|
-
severity: typeof c.severity === "string" ? c.severity : undefined
|
|
36395
|
-
}));
|
|
36396
|
-
} catch {
|
|
36397
|
-
return [];
|
|
36398
|
-
}
|
|
36725
|
+
return loadCorpusEntries().map((c) => ({
|
|
36726
|
+
cve: c.cve,
|
|
36727
|
+
name: c.name,
|
|
36728
|
+
product: c.product,
|
|
36729
|
+
class: "",
|
|
36730
|
+
epss: c.epss,
|
|
36731
|
+
reports: 0,
|
|
36732
|
+
fingerprint: c.product,
|
|
36733
|
+
match: c.match,
|
|
36734
|
+
fixed_in: null,
|
|
36735
|
+
version_key: null,
|
|
36736
|
+
severity: c.severity
|
|
36737
|
+
}));
|
|
36399
36738
|
}
|
|
36400
36739
|
function fmtPayout(min, max) {
|
|
36401
36740
|
if (min == null || max == null)
|
|
@@ -36477,12 +36816,12 @@ function watchlistCveMatches(techs, headers = {}, body = "", versions = [], max
|
|
|
36477
36816
|
}
|
|
36478
36817
|
|
|
36479
36818
|
// src/surface-map.ts
|
|
36480
|
-
import { readFileSync as
|
|
36481
|
-
import { join as
|
|
36482
|
-
import { fileURLToPath as
|
|
36483
|
-
var
|
|
36819
|
+
import { readFileSync as readFileSync13 } from "node:fs";
|
|
36820
|
+
import { join as join14 } from "node:path";
|
|
36821
|
+
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
36822
|
+
var ROOT6 = join14(fileURLToPath8(new URL(".", import.meta.url)), "..");
|
|
36484
36823
|
function load2() {
|
|
36485
|
-
const raw =
|
|
36824
|
+
const raw = readFileSync13(join14(ROOT6, "intelligence", "surface-map.json"), "utf8");
|
|
36486
36825
|
return JSON.parse(raw);
|
|
36487
36826
|
}
|
|
36488
36827
|
function surfaceMap(hint = "") {
|
|
@@ -37066,7 +37405,7 @@ function classifyTarget(target) {
|
|
|
37066
37405
|
if (/^https?:\/\//i.test(target))
|
|
37067
37406
|
return { kind: "live", target };
|
|
37068
37407
|
try {
|
|
37069
|
-
if (
|
|
37408
|
+
if (existsSync9(target) && (statSync3(target).isDirectory() || statSync3(target).isFile())) {
|
|
37070
37409
|
return { kind: "source", target };
|
|
37071
37410
|
}
|
|
37072
37411
|
} catch {}
|
|
@@ -37082,9 +37421,9 @@ function loadChains() {
|
|
|
37082
37421
|
if (_chainsCache)
|
|
37083
37422
|
return _chainsCache;
|
|
37084
37423
|
try {
|
|
37085
|
-
const dir =
|
|
37086
|
-
const path =
|
|
37087
|
-
const raw = JSON.parse(
|
|
37424
|
+
const dir = join15(fileURLToPath9(new URL(".", import.meta.url)), "..");
|
|
37425
|
+
const path = join15(dir, "chains.json");
|
|
37426
|
+
const raw = JSON.parse(readFileSync14(path, "utf8"));
|
|
37088
37427
|
_chainsCache = raw.chains ?? [];
|
|
37089
37428
|
return _chainsCache;
|
|
37090
37429
|
} catch {
|
|
@@ -37207,7 +37546,7 @@ function runEngagement(target, scope = "", mode = "bug-bounty", maxFiles = 2000,
|
|
|
37207
37546
|
};
|
|
37208
37547
|
const isPath = (() => {
|
|
37209
37548
|
try {
|
|
37210
|
-
return
|
|
37549
|
+
return existsSync9(target) && (statSync3(target).isDirectory() || statSync3(target).isFile());
|
|
37211
37550
|
} catch {
|
|
37212
37551
|
return false;
|
|
37213
37552
|
}
|
|
@@ -37865,8 +38204,8 @@ var CHAIN_ID_TO_ESCALATION = {
|
|
|
37865
38204
|
};
|
|
37866
38205
|
function loadChainLinks() {
|
|
37867
38206
|
try {
|
|
37868
|
-
const dir =
|
|
37869
|
-
const data = JSON.parse(
|
|
38207
|
+
const dir = join15(fileURLToPath9(new URL(".", import.meta.url)), "..");
|
|
38208
|
+
const data = JSON.parse(readFileSync14(join15(dir, "intelligence", "chain_links.json"), "utf8"));
|
|
37870
38209
|
return data.links ?? [];
|
|
37871
38210
|
} catch {
|
|
37872
38211
|
return [];
|
|
@@ -38022,18 +38361,18 @@ function compactState(phase, findings) {
|
|
|
38022
38361
|
}
|
|
38023
38362
|
|
|
38024
38363
|
// src/tasks.ts
|
|
38025
|
-
import { mkdirSync as mkdirSync6, readFileSync as
|
|
38026
|
-
import { join as
|
|
38027
|
-
import { fileURLToPath as
|
|
38364
|
+
import { mkdirSync as mkdirSync6, readFileSync as readFileSync15, writeFileSync as writeFileSync3 } from "node:fs";
|
|
38365
|
+
import { join as join16 } from "node:path";
|
|
38366
|
+
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
38028
38367
|
function tasksDir() {
|
|
38029
|
-
return
|
|
38368
|
+
return join16(fileURLToPath10(new URL(".", import.meta.url)), "..", ".blitzstrike", "tasks");
|
|
38030
38369
|
}
|
|
38031
38370
|
function taskPath(id) {
|
|
38032
|
-
return
|
|
38371
|
+
return join16(tasksDir(), `${id}.json`);
|
|
38033
38372
|
}
|
|
38034
38373
|
function load3(id) {
|
|
38035
38374
|
try {
|
|
38036
|
-
return JSON.parse(
|
|
38375
|
+
return JSON.parse(readFileSync15(taskPath(id), "utf8"));
|
|
38037
38376
|
} catch {
|
|
38038
38377
|
return null;
|
|
38039
38378
|
}
|
|
@@ -38373,16 +38712,16 @@ function scaffoldEngagement(target, scope = [], out_of_scope = []) {
|
|
|
38373
38712
|
// src/incremental.ts
|
|
38374
38713
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
38375
38714
|
import { writeFileSync as writeFileSync4, mkdtempSync, rmSync } from "node:fs";
|
|
38376
|
-
import { join as
|
|
38715
|
+
import { join as join17 } from "node:path";
|
|
38377
38716
|
import { tmpdir } from "node:os";
|
|
38378
38717
|
|
|
38379
38718
|
// src/eagle2.ts
|
|
38380
38719
|
var import_php_parser2 = __toESM(require_src(), 1);
|
|
38381
|
-
import { readFileSync as
|
|
38720
|
+
import { readFileSync as readFileSync18 } from "node:fs";
|
|
38382
38721
|
|
|
38383
38722
|
// src/dataflow.ts
|
|
38384
38723
|
init_scanner();
|
|
38385
|
-
import { readFileSync as
|
|
38724
|
+
import { readFileSync as readFileSync16 } from "node:fs";
|
|
38386
38725
|
var SOURCES = {
|
|
38387
38726
|
$_GET: { id: "http_get", label: "HTTP GET parameter", attacker_controlled: true },
|
|
38388
38727
|
$_POST: { id: "http_post", label: "HTTP POST body", attacker_controlled: true },
|
|
@@ -38467,7 +38806,7 @@ function traceDataFlow(path) {
|
|
|
38467
38806
|
return result;
|
|
38468
38807
|
let text;
|
|
38469
38808
|
try {
|
|
38470
|
-
text =
|
|
38809
|
+
text = readFileSync16(path, "utf8");
|
|
38471
38810
|
} catch {
|
|
38472
38811
|
return result;
|
|
38473
38812
|
}
|
|
@@ -38548,7 +38887,7 @@ init_scanner();
|
|
|
38548
38887
|
|
|
38549
38888
|
// src/callgraph.ts
|
|
38550
38889
|
var import_php_parser = __toESM(require_src(), 1);
|
|
38551
|
-
import { readFileSync as
|
|
38890
|
+
import { readFileSync as readFileSync17 } from "node:fs";
|
|
38552
38891
|
var parser = new import_php_parser.Engine({
|
|
38553
38892
|
parser: { extractDoc: false, php7: true },
|
|
38554
38893
|
ast: { withPositions: true, withSource: false }
|
|
@@ -38609,7 +38948,7 @@ function buildCallGraph(path) {
|
|
|
38609
38948
|
const g = { nodes: new Map, edges: [] };
|
|
38610
38949
|
let code;
|
|
38611
38950
|
try {
|
|
38612
|
-
code =
|
|
38951
|
+
code = readFileSync17(path, "utf8");
|
|
38613
38952
|
} catch {
|
|
38614
38953
|
return g;
|
|
38615
38954
|
}
|
|
@@ -39271,7 +39610,7 @@ function resolveFuncId(name, summaries) {
|
|
|
39271
39610
|
function analyzeDataFlow2(path) {
|
|
39272
39611
|
let cacheCode = "";
|
|
39273
39612
|
try {
|
|
39274
|
-
cacheCode =
|
|
39613
|
+
cacheCode = readFileSync18(path, "utf8");
|
|
39275
39614
|
} catch {}
|
|
39276
39615
|
if (cacheCode) {
|
|
39277
39616
|
const cached = getCache("eagle2", cacheCode);
|
|
@@ -39293,7 +39632,7 @@ function analyzeDataFlow2(path) {
|
|
|
39293
39632
|
};
|
|
39294
39633
|
let code;
|
|
39295
39634
|
try {
|
|
39296
|
-
code = cacheCode ||
|
|
39635
|
+
code = cacheCode || readFileSync18(path, "utf8");
|
|
39297
39636
|
} catch {
|
|
39298
39637
|
return result;
|
|
39299
39638
|
}
|
|
@@ -57979,8 +58318,8 @@ function analyzeChangedFiles(repo, base = "HEAD~1", head = "HEAD") {
|
|
|
57979
58318
|
continue;
|
|
57980
58319
|
const lang = detectLanguage(file)?.language;
|
|
57981
58320
|
if (lang === "php") {
|
|
57982
|
-
const dir = mkdtempSync(
|
|
57983
|
-
const tmp =
|
|
58321
|
+
const dir = mkdtempSync(join17(tmpdir(), "blitz-incr-"));
|
|
58322
|
+
const tmp = join17(dir, "changed.php");
|
|
57984
58323
|
writeFileSync4(tmp, code);
|
|
57985
58324
|
try {
|
|
57986
58325
|
const r = analyzeDataFlow2(tmp);
|
|
@@ -58001,7 +58340,7 @@ function analyzeChangedFiles(repo, base = "HEAD~1", head = "HEAD") {
|
|
|
58001
58340
|
// src/taint.ts
|
|
58002
58341
|
init_scanner();
|
|
58003
58342
|
var import_php_parser4 = __toESM(require_src(), 1);
|
|
58004
|
-
import { readFileSync as
|
|
58343
|
+
import { readFileSync as readFileSync19 } from "node:fs";
|
|
58005
58344
|
var parser4 = new import_php_parser4.Engine({
|
|
58006
58345
|
parser: { extractDoc: false, php7: true },
|
|
58007
58346
|
ast: { withPositions: true, withSource: false }
|
|
@@ -58299,7 +58638,7 @@ function analyzeTaint(path) {
|
|
|
58299
58638
|
const result = { file: path, findings: [], suppressed: 0 };
|
|
58300
58639
|
let code;
|
|
58301
58640
|
try {
|
|
58302
|
-
code =
|
|
58641
|
+
code = readFileSync19(path, "utf8");
|
|
58303
58642
|
} catch {
|
|
58304
58643
|
return result;
|
|
58305
58644
|
}
|
|
@@ -58393,15 +58732,15 @@ function taintTree(root, maxFiles = 2000) {
|
|
|
58393
58732
|
}
|
|
58394
58733
|
|
|
58395
58734
|
// src/differential.ts
|
|
58396
|
-
import { writeFileSync as writeFileSync5, rmSync as rmSync2, mkdtempSync as mkdtempSync2, readFileSync as
|
|
58397
|
-
import { join as
|
|
58735
|
+
import { writeFileSync as writeFileSync5, rmSync as rmSync2, mkdtempSync as mkdtempSync2, readFileSync as readFileSync20 } from "node:fs";
|
|
58736
|
+
import { join as join18 } from "node:path";
|
|
58398
58737
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
58399
58738
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
58400
58739
|
init_scanner();
|
|
58401
58740
|
function runEngine(code, language, file) {
|
|
58402
58741
|
if (language === "php") {
|
|
58403
|
-
const dir = mkdtempSync2(
|
|
58404
|
-
const tmp =
|
|
58742
|
+
const dir = mkdtempSync2(join18(tmpdir2(), "blitz-diff-"));
|
|
58743
|
+
const tmp = join18(dir, "old.php");
|
|
58405
58744
|
writeFileSync5(tmp, code);
|
|
58406
58745
|
try {
|
|
58407
58746
|
const r = analyzeDataFlow2(tmp);
|
|
@@ -58555,8 +58894,8 @@ function languageOf(file) {
|
|
|
58555
58894
|
return adapter?.language ?? "php";
|
|
58556
58895
|
}
|
|
58557
58896
|
function analyzeDifferentialFiles(oldPath, newPath, language) {
|
|
58558
|
-
const oldCode =
|
|
58559
|
-
const newCode =
|
|
58897
|
+
const oldCode = readFileSync20(oldPath, "utf8");
|
|
58898
|
+
const newCode = readFileSync20(newPath, "utf8");
|
|
58560
58899
|
const lang = language ?? languageOf(newPath);
|
|
58561
58900
|
return analyzeDifferential(oldCode, newCode, lang, newPath);
|
|
58562
58901
|
}
|
|
@@ -58683,28 +59022,28 @@ function analyzePatch(oldCode, newCode, language = "php") {
|
|
|
58683
59022
|
};
|
|
58684
59023
|
}
|
|
58685
59024
|
function analyzePatchFiles(oldPath, newPath, language) {
|
|
58686
|
-
const oldCode =
|
|
58687
|
-
const newCode =
|
|
59025
|
+
const oldCode = readFileSync20(oldPath, "utf8");
|
|
59026
|
+
const newCode = readFileSync20(newPath, "utf8");
|
|
58688
59027
|
const lang = language ?? languageOf(newPath);
|
|
58689
59028
|
return analyzePatch(oldCode, newCode, lang);
|
|
58690
59029
|
}
|
|
58691
59030
|
|
|
58692
59031
|
// src/frameworks.ts
|
|
58693
|
-
import { readFileSync as
|
|
58694
|
-
import { join as
|
|
58695
|
-
import { fileURLToPath as
|
|
58696
|
-
var
|
|
58697
|
-
var INTEL2 =
|
|
58698
|
-
var
|
|
59032
|
+
import { readFileSync as readFileSync21, existsSync as existsSync10 } from "node:fs";
|
|
59033
|
+
import { join as join19 } from "node:path";
|
|
59034
|
+
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
59035
|
+
var ROOT7 = join19(fileURLToPath11(new URL(".", import.meta.url)), "..");
|
|
59036
|
+
var INTEL2 = join19(ROOT7, "intelligence");
|
|
59037
|
+
var cache2 = null;
|
|
58699
59038
|
function load4() {
|
|
58700
|
-
if (
|
|
58701
|
-
return
|
|
58702
|
-
const p =
|
|
58703
|
-
if (!
|
|
59039
|
+
if (cache2)
|
|
59040
|
+
return cache2;
|
|
59041
|
+
const p = join19(INTEL2, "frameworks.json");
|
|
59042
|
+
if (!existsSync10(p))
|
|
58704
59043
|
return null;
|
|
58705
59044
|
try {
|
|
58706
|
-
|
|
58707
|
-
return
|
|
59045
|
+
cache2 = JSON.parse(readFileSync21(p, "utf8"));
|
|
59046
|
+
return cache2;
|
|
58708
59047
|
} catch {
|
|
58709
59048
|
return null;
|
|
58710
59049
|
}
|
|
@@ -59214,8 +59553,8 @@ function nextSteps(ctx) {
|
|
|
59214
59553
|
// src/git-history.ts
|
|
59215
59554
|
init_complex_bugs();
|
|
59216
59555
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
59217
|
-
import { existsSync as
|
|
59218
|
-
import { join as
|
|
59556
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
59557
|
+
import { join as join20 } from "node:path";
|
|
59219
59558
|
function parseDeletions(output) {
|
|
59220
59559
|
const out = [];
|
|
59221
59560
|
let commit = "";
|
|
@@ -59244,7 +59583,7 @@ function blobBeforeDeletion(root, commit, path) {
|
|
|
59244
59583
|
function scanGitHistory(root, opts) {
|
|
59245
59584
|
const limit = opts?.limit ?? 30;
|
|
59246
59585
|
const findings = [];
|
|
59247
|
-
if (!
|
|
59586
|
+
if (!existsSync12(join20(root, ".git"))) {
|
|
59248
59587
|
return { root, is_git_repo: false, total: 0, findings: [], error: "not a git repository (no .git dir)" };
|
|
59249
59588
|
}
|
|
59250
59589
|
if (opts?.secretPattern) {
|
|
@@ -59391,13 +59730,13 @@ async function validateLeakedKey(input) {
|
|
|
59391
59730
|
}
|
|
59392
59731
|
|
|
59393
59732
|
// src/hackbot-arena.ts
|
|
59394
|
-
import { readFileSync as
|
|
59395
|
-
import { join as
|
|
59396
|
-
import { fileURLToPath as
|
|
59397
|
-
var __dirname3 = dirname3(
|
|
59733
|
+
import { readFileSync as readFileSync22 } from "node:fs";
|
|
59734
|
+
import { join as join21, dirname as dirname3 } from "node:path";
|
|
59735
|
+
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
59736
|
+
var __dirname3 = dirname3(fileURLToPath12(import.meta.url));
|
|
59398
59737
|
function load5() {
|
|
59399
59738
|
try {
|
|
59400
|
-
return JSON.parse(
|
|
59739
|
+
return JSON.parse(readFileSync22(join21(__dirname3, "..", "intelligence", "hackbot-arena.json"), "utf8"));
|
|
59401
59740
|
} catch {
|
|
59402
59741
|
return { total: 0, flag_format: "FLAG{nusasec-<32 hex>}", labs: [] };
|
|
59403
59742
|
}
|
|
@@ -59561,13 +59900,13 @@ function listSeverityMap() {
|
|
|
59561
59900
|
}
|
|
59562
59901
|
|
|
59563
59902
|
// src/datarefresh.ts
|
|
59564
|
-
import { readFileSync as
|
|
59565
|
-
import { join as
|
|
59566
|
-
import { fileURLToPath as
|
|
59567
|
-
var __dirname4 = dirname4(
|
|
59903
|
+
import { readFileSync as readFileSync23 } from "node:fs";
|
|
59904
|
+
import { join as join22, dirname as dirname4 } from "node:path";
|
|
59905
|
+
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
59906
|
+
var __dirname4 = dirname4(fileURLToPath13(import.meta.url));
|
|
59568
59907
|
function loadJson2(rel) {
|
|
59569
59908
|
try {
|
|
59570
|
-
return JSON.parse(
|
|
59909
|
+
return JSON.parse(readFileSync23(join22(__dirname4, "..", rel), "utf8"));
|
|
59571
59910
|
} catch {
|
|
59572
59911
|
return null;
|
|
59573
59912
|
}
|
|
@@ -59759,18 +60098,18 @@ async function brokenLinkScan(url, maxHosts = 30) {
|
|
|
59759
60098
|
}
|
|
59760
60099
|
|
|
59761
60100
|
// src/benchmark.ts
|
|
59762
|
-
import { readFileSync as
|
|
59763
|
-
import { join as
|
|
59764
|
-
import { fileURLToPath as
|
|
59765
|
-
import { tmpdir as tmpdir3, homedir as
|
|
60101
|
+
import { readFileSync as readFileSync25, readdirSync as readdirSync6, writeFileSync as writeFileSync6, rmSync as rmSync3, mkdirSync as mkdirSync7 } from "node:fs";
|
|
60102
|
+
import { join as join24 } from "node:path";
|
|
60103
|
+
import { fileURLToPath as fileURLToPath15 } from "node:url";
|
|
60104
|
+
import { tmpdir as tmpdir3, homedir as homedir9 } from "node:os";
|
|
59766
60105
|
init_complex_bugs();
|
|
59767
|
-
var
|
|
59768
|
-
var CORPUS =
|
|
59769
|
-
var CAPTURED_CORPUS_DIR = process.env.BLITZSTRIKE_CORPUS_DIR ??
|
|
60106
|
+
var ROOT8 = join24(fileURLToPath15(new URL(".", import.meta.url)), "..");
|
|
60107
|
+
var CORPUS = join24(ROOT8, "bench", "corpus");
|
|
60108
|
+
var CAPTURED_CORPUS_DIR = process.env.BLITZSTRIKE_CORPUS_DIR ?? join24(homedir9(), ".blitzstrike", "corpus");
|
|
59770
60109
|
function parseCorpusFile(path) {
|
|
59771
60110
|
let text;
|
|
59772
60111
|
try {
|
|
59773
|
-
text =
|
|
60112
|
+
text = readFileSync25(path, "utf8");
|
|
59774
60113
|
} catch {
|
|
59775
60114
|
return null;
|
|
59776
60115
|
}
|
|
@@ -59823,10 +60162,10 @@ function parseCorpusFile(path) {
|
|
|
59823
60162
|
function loadDir(dir) {
|
|
59824
60163
|
const entries = [];
|
|
59825
60164
|
try {
|
|
59826
|
-
for (const f of
|
|
60165
|
+
for (const f of readdirSync6(dir)) {
|
|
59827
60166
|
if (!f.endsWith(".md"))
|
|
59828
60167
|
continue;
|
|
59829
|
-
const e = parseCorpusFile(
|
|
60168
|
+
const e = parseCorpusFile(join24(dir, f));
|
|
59830
60169
|
if (e)
|
|
59831
60170
|
entries.push(e);
|
|
59832
60171
|
}
|
|
@@ -59853,7 +60192,7 @@ function captureFalsePositive(input) {
|
|
|
59853
60192
|
input.code,
|
|
59854
60193
|
"```"
|
|
59855
60194
|
].filter((l) => l !== null);
|
|
59856
|
-
const path =
|
|
60195
|
+
const path = join24(CAPTURED_CORPUS_DIR, `${id}.md`);
|
|
59857
60196
|
writeFileSync6(path, lines.join(`
|
|
59858
60197
|
`) + `
|
|
59859
60198
|
`, "utf8");
|
|
@@ -59875,7 +60214,7 @@ function detect(entry) {
|
|
|
59875
60214
|
}
|
|
59876
60215
|
const lang = entry.language;
|
|
59877
60216
|
if (lang === "php") {
|
|
59878
|
-
const tmp =
|
|
60217
|
+
const tmp = join24(tmpdir3(), `blitzstrike-bench-${entry.id}-${process.pid}.php`);
|
|
59879
60218
|
writeFileSync6(tmp, entry.code);
|
|
59880
60219
|
const r = analyzeDataFlow2(tmp);
|
|
59881
60220
|
rmSync3(tmp, { force: true });
|
|
@@ -59944,25 +60283,25 @@ function runBenchmark() {
|
|
|
59944
60283
|
}
|
|
59945
60284
|
|
|
59946
60285
|
// src/obligations.ts
|
|
59947
|
-
import { readFileSync as
|
|
59948
|
-
import { join as
|
|
60286
|
+
import { readFileSync as readFileSync26, appendFileSync as appendFileSync4, mkdirSync as mkdirSync8, existsSync as existsSync13, writeFileSync as writeFileSync7 } from "node:fs";
|
|
60287
|
+
import { join as join25 } from "node:path";
|
|
59949
60288
|
import { createHash as createHash6 } from "node:crypto";
|
|
59950
|
-
import { homedir as
|
|
59951
|
-
var HOME_DIR4 = process.env.BLITZSTRIKE_HOME ??
|
|
59952
|
-
var OBLIGATION_PATH =
|
|
60289
|
+
import { homedir as homedir10 } from "node:os";
|
|
60290
|
+
var HOME_DIR4 = process.env.BLITZSTRIKE_HOME ?? join25(homedir10(), ".blitzstrike");
|
|
60291
|
+
var OBLIGATION_PATH = join25(HOME_DIR4, "obligations.jsonl");
|
|
59953
60292
|
function ensureDir3() {
|
|
59954
|
-
if (!
|
|
60293
|
+
if (!existsSync13(HOME_DIR4))
|
|
59955
60294
|
mkdirSync8(HOME_DIR4, { recursive: true });
|
|
59956
60295
|
}
|
|
59957
60296
|
function shortId2(claim) {
|
|
59958
60297
|
return `obl-${createHash6("sha256").update(`${claim}\x00${Date.now()}`).digest("hex").slice(0, 12)}`;
|
|
59959
60298
|
}
|
|
59960
60299
|
function loadObligations() {
|
|
59961
|
-
if (!
|
|
60300
|
+
if (!existsSync13(OBLIGATION_PATH))
|
|
59962
60301
|
return [];
|
|
59963
60302
|
try {
|
|
59964
60303
|
const out = [];
|
|
59965
|
-
for (const line of
|
|
60304
|
+
for (const line of readFileSync26(OBLIGATION_PATH, "utf8").split(`
|
|
59966
60305
|
`)) {
|
|
59967
60306
|
const t = line.trim();
|
|
59968
60307
|
if (!t)
|
|
@@ -60066,11 +60405,11 @@ init_framework_security();
|
|
|
60066
60405
|
// src/variant-scan.ts
|
|
60067
60406
|
init_scanner();
|
|
60068
60407
|
init_complex_bugs();
|
|
60069
|
-
import { readFileSync as
|
|
60408
|
+
import { readFileSync as readFileSync28 } from "node:fs";
|
|
60070
60409
|
|
|
60071
60410
|
// src/cross-file.ts
|
|
60072
60411
|
init_scanner();
|
|
60073
|
-
import { readFileSync as
|
|
60412
|
+
import { readFileSync as readFileSync27 } from "node:fs";
|
|
60074
60413
|
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)/;
|
|
60075
60414
|
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*\(/;
|
|
60076
60415
|
var ROLE_META_RE = /update_user_meta\s*\(\s*[^,]+,\s*['"](wp_capabilities|role|roles|capabilities|wp_user_level)['"]/;
|
|
@@ -60122,7 +60461,7 @@ function detectCrossFilePrivesc(root) {
|
|
|
60122
60461
|
for (const file of files) {
|
|
60123
60462
|
let code;
|
|
60124
60463
|
try {
|
|
60125
|
-
code = stripComments(
|
|
60464
|
+
code = stripComments(readFileSync27(file, "utf8"));
|
|
60126
60465
|
} catch {
|
|
60127
60466
|
continue;
|
|
60128
60467
|
}
|
|
@@ -60163,7 +60502,7 @@ function detectCrossFilePrivesc(root) {
|
|
|
60163
60502
|
for (const file of files) {
|
|
60164
60503
|
let code;
|
|
60165
60504
|
try {
|
|
60166
|
-
code = stripComments(
|
|
60505
|
+
code = stripComments(readFileSync27(file, "utf8"));
|
|
60167
60506
|
} catch {
|
|
60168
60507
|
continue;
|
|
60169
60508
|
}
|
|
@@ -60186,7 +60525,7 @@ function detectCrossFilePrivesc(root) {
|
|
|
60186
60525
|
for (const file of files) {
|
|
60187
60526
|
let code;
|
|
60188
60527
|
try {
|
|
60189
|
-
code = stripComments(
|
|
60528
|
+
code = stripComments(readFileSync27(file, "utf8"));
|
|
60190
60529
|
} catch {
|
|
60191
60530
|
continue;
|
|
60192
60531
|
}
|
|
@@ -60301,7 +60640,7 @@ function variantScan(root, opts = {}) {
|
|
|
60301
60640
|
for (const file of files) {
|
|
60302
60641
|
let code;
|
|
60303
60642
|
try {
|
|
60304
|
-
code =
|
|
60643
|
+
code = readFileSync28(file, "utf8");
|
|
60305
60644
|
} catch {
|
|
60306
60645
|
continue;
|
|
60307
60646
|
}
|
|
@@ -60965,7 +61304,7 @@ import { spawn as spawn3, execSync as execSync2 } from "node:child_process";
|
|
|
60965
61304
|
import { createServer } from "node:http";
|
|
60966
61305
|
import { randomUUID } from "node:crypto";
|
|
60967
61306
|
import { networkInterfaces } from "node:os";
|
|
60968
|
-
import { existsSync as
|
|
61307
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
60969
61308
|
var sessions = new Map;
|
|
60970
61309
|
function sleep(ms) {
|
|
60971
61310
|
return new Promise((r) => setTimeout(r, ms));
|
|
@@ -60979,7 +61318,7 @@ function findInteractsh() {
|
|
|
60979
61318
|
const home = process.env.HOME ?? "/root";
|
|
60980
61319
|
const candidates = [`${home}/go/bin/interactsh-client`, "/usr/local/bin/interactsh-client", "/usr/bin/interactsh-client"];
|
|
60981
61320
|
for (const c of candidates)
|
|
60982
|
-
if (
|
|
61321
|
+
if (existsSync14(c))
|
|
60983
61322
|
return c;
|
|
60984
61323
|
return null;
|
|
60985
61324
|
}
|
|
@@ -61984,9 +62323,9 @@ function listPocTypes() {
|
|
|
61984
62323
|
|
|
61985
62324
|
// src/foundry-run.ts
|
|
61986
62325
|
import { execSync as execSync3 } from "node:child_process";
|
|
61987
|
-
import { mkdtempSync as mkdtempSync3, mkdirSync as mkdirSync9, writeFileSync as writeFileSync8, rmSync as rmSync4, existsSync as
|
|
62326
|
+
import { mkdtempSync as mkdtempSync3, mkdirSync as mkdirSync9, writeFileSync as writeFileSync8, rmSync as rmSync4, existsSync as existsSync15 } from "node:fs";
|
|
61988
62327
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
61989
|
-
import { join as
|
|
62328
|
+
import { join as join26 } from "node:path";
|
|
61990
62329
|
function findForge() {
|
|
61991
62330
|
try {
|
|
61992
62331
|
const p = execSync3("which forge 2>/dev/null", { encoding: "utf8", timeout: 3000 }).trim();
|
|
@@ -61996,7 +62335,7 @@ function findForge() {
|
|
|
61996
62335
|
const home = process.env.HOME ?? "/root";
|
|
61997
62336
|
const candidates = [`${home}/.foundry/bin/forge`, "/usr/local/bin/forge", "/usr/bin/forge"];
|
|
61998
62337
|
for (const c of candidates)
|
|
61999
|
-
if (
|
|
62338
|
+
if (existsSync15(c))
|
|
62000
62339
|
return c;
|
|
62001
62340
|
return null;
|
|
62002
62341
|
}
|
|
@@ -62035,14 +62374,14 @@ async function foundryRun(input) {
|
|
|
62035
62374
|
};
|
|
62036
62375
|
}
|
|
62037
62376
|
const poc = input.poc_code ?? foundryPoc(input.class_ ?? "missing_access_control", name);
|
|
62038
|
-
const dir = mkdtempSync3(
|
|
62377
|
+
const dir = mkdtempSync3(join26(tmpdir4(), "blitzstrike-foundry-"));
|
|
62039
62378
|
try {
|
|
62040
62379
|
try {
|
|
62041
62380
|
execSync3(`${forge} init --force --no-git ${dir}`, { stdio: "ignore", timeout: 60000 });
|
|
62042
62381
|
} catch {
|
|
62043
|
-
mkdirSync9(
|
|
62044
|
-
mkdirSync9(
|
|
62045
|
-
writeFileSync8(
|
|
62382
|
+
mkdirSync9(join26(dir, "src"), { recursive: true });
|
|
62383
|
+
mkdirSync9(join26(dir, "test"), { recursive: true });
|
|
62384
|
+
writeFileSync8(join26(dir, "foundry.toml"), `[profile.default]
|
|
62046
62385
|
src = "src"
|
|
62047
62386
|
out = "out"
|
|
62048
62387
|
libs = ["lib"]
|
|
@@ -62052,12 +62391,12 @@ solc = "0.8.20"
|
|
|
62052
62391
|
for (const f of ["Counter.sol", "Counter.t.sol", "Counter.s.sol"]) {
|
|
62053
62392
|
for (const sub of ["src", "test", "script"]) {
|
|
62054
62393
|
try {
|
|
62055
|
-
rmSync4(
|
|
62394
|
+
rmSync4(join26(dir, sub, f), { force: true });
|
|
62056
62395
|
} catch {}
|
|
62057
62396
|
}
|
|
62058
62397
|
}
|
|
62059
|
-
writeFileSync8(
|
|
62060
|
-
writeFileSync8(
|
|
62398
|
+
writeFileSync8(join26(dir, "src", `${name}.sol`), input.contract_code);
|
|
62399
|
+
writeFileSync8(join26(dir, "test", `${name}.t.sol`), poc);
|
|
62061
62400
|
const { out } = runForge(forge, dir, input.timeout_ms ?? 60000);
|
|
62062
62401
|
const tests = parseTestResults(out);
|
|
62063
62402
|
const anyFail = tests.some((t) => t.status === "fail");
|
|
@@ -62075,33 +62414,33 @@ solc = "0.8.20"
|
|
|
62075
62414
|
}
|
|
62076
62415
|
|
|
62077
62416
|
// src/enterprise-benchmark.ts
|
|
62078
|
-
import { existsSync as
|
|
62079
|
-
import { join as
|
|
62080
|
-
import { fileURLToPath as
|
|
62417
|
+
import { existsSync as existsSync16, readFileSync as readFileSync29, readdirSync as readdirSync7, statSync as statSync4 } from "node:fs";
|
|
62418
|
+
import { join as join27, resolve } from "node:path";
|
|
62419
|
+
import { fileURLToPath as fileURLToPath16 } from "node:url";
|
|
62081
62420
|
init_complex_bugs();
|
|
62082
|
-
var
|
|
62421
|
+
var ROOT9 = resolve(fileURLToPath16(new URL(".", import.meta.url)), "..", "bench", "enterprise");
|
|
62083
62422
|
var ENTERPRISE_FIXTURES = [
|
|
62084
|
-
{ id: "php-laravel", dir:
|
|
62085
|
-
{ id: "js-express", dir:
|
|
62086
|
-
{ id: "py-django", dir:
|
|
62087
|
-
{ id: "java-spring", dir:
|
|
62088
|
-
{ id: "wp-batch-route", dir:
|
|
62089
|
-
{ id: "php-complex", dir:
|
|
62423
|
+
{ id: "php-laravel", dir: join27(ROOT9, "php-laravel"), expected_vulns: 4 },
|
|
62424
|
+
{ id: "js-express", dir: join27(ROOT9, "js-express"), expected_vulns: 2 },
|
|
62425
|
+
{ id: "py-django", dir: join27(ROOT9, "py-django"), expected_vulns: 2 },
|
|
62426
|
+
{ id: "java-spring", dir: join27(ROOT9, "java-spring"), expected_vulns: 2 },
|
|
62427
|
+
{ id: "wp-batch-route", dir: join27(ROOT9, "wp-batch-route"), expected_vulns: 3 },
|
|
62428
|
+
{ id: "php-complex", dir: join27(ROOT9, "php-complex"), expected_vulns: 4 }
|
|
62090
62429
|
];
|
|
62091
62430
|
function sourceFiles(root) {
|
|
62092
62431
|
const out = [];
|
|
62093
62432
|
const walk = (dir) => {
|
|
62094
62433
|
let entries;
|
|
62095
62434
|
try {
|
|
62096
|
-
entries =
|
|
62435
|
+
entries = readdirSync7(dir);
|
|
62097
62436
|
} catch {
|
|
62098
62437
|
return;
|
|
62099
62438
|
}
|
|
62100
62439
|
for (const e of entries) {
|
|
62101
|
-
const p =
|
|
62440
|
+
const p = join27(dir, e);
|
|
62102
62441
|
let st;
|
|
62103
62442
|
try {
|
|
62104
|
-
st =
|
|
62443
|
+
st = statSync4(p);
|
|
62105
62444
|
} catch {
|
|
62106
62445
|
continue;
|
|
62107
62446
|
}
|
|
@@ -62119,7 +62458,7 @@ function detectFixture(dir) {
|
|
|
62119
62458
|
for (const f of sourceFiles(dir)) {
|
|
62120
62459
|
let code;
|
|
62121
62460
|
try {
|
|
62122
|
-
code =
|
|
62461
|
+
code = readFileSync29(f, "utf8");
|
|
62123
62462
|
} catch {
|
|
62124
62463
|
continue;
|
|
62125
62464
|
}
|
|
@@ -62137,7 +62476,7 @@ function detectFixture(dir) {
|
|
|
62137
62476
|
function runEnterpriseBenchmark() {
|
|
62138
62477
|
const fixtures = [];
|
|
62139
62478
|
for (const fx of ENTERPRISE_FIXTURES) {
|
|
62140
|
-
if (!
|
|
62479
|
+
if (!existsSync16(fx.dir)) {
|
|
62141
62480
|
fixtures.push({ id: fx.id, available: false, detected: 0, expected: fx.expected_vulns, recall: 0 });
|
|
62142
62481
|
continue;
|
|
62143
62482
|
}
|
|
@@ -63223,7 +63562,7 @@ ${statusLine}` : statusLine },
|
|
|
63223
63562
|
let src = code;
|
|
63224
63563
|
if (!src && path) {
|
|
63225
63564
|
try {
|
|
63226
|
-
src =
|
|
63565
|
+
src = readFileSync31(path, "utf8");
|
|
63227
63566
|
} catch {
|
|
63228
63567
|
return { content: [{ type: "text", text: JSON.stringify({ error: "unreadable path" }) }] };
|
|
63229
63568
|
}
|
|
@@ -63304,7 +63643,7 @@ ${statusLine}` : statusLine },
|
|
|
63304
63643
|
let src = code;
|
|
63305
63644
|
if (!src && path) {
|
|
63306
63645
|
try {
|
|
63307
|
-
src =
|
|
63646
|
+
src = readFileSync31(path, "utf8");
|
|
63308
63647
|
} catch {
|
|
63309
63648
|
return { content: [{ type: "text", text: JSON.stringify({ error: "unreadable path" }) }] };
|
|
63310
63649
|
}
|
|
@@ -63386,6 +63725,27 @@ ${statusLine}` : statusLine },
|
|
|
63386
63725
|
}, async ({ hint }) => {
|
|
63387
63726
|
return { content: [{ type: "text", text: JSON.stringify(surfaceMap(hint ?? "")) }] };
|
|
63388
63727
|
});
|
|
63728
|
+
server.registerTool("sync_cve_corpus", {
|
|
63729
|
+
title: "Refresh the CVE fingerprint corpus from nuclei-templates",
|
|
63730
|
+
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.",
|
|
63731
|
+
inputSchema: {}
|
|
63732
|
+
}, async () => {
|
|
63733
|
+
let update = "skipped (nuclei not found)";
|
|
63734
|
+
try {
|
|
63735
|
+
execFileSync6("nuclei", ["-update-templates"], { timeout: 120000, stdio: "pipe" });
|
|
63736
|
+
update = "ok";
|
|
63737
|
+
} catch {}
|
|
63738
|
+
invalidateCorpusCache();
|
|
63739
|
+
const corpus = loadCorpusEntries();
|
|
63740
|
+
return {
|
|
63741
|
+
content: [
|
|
63742
|
+
{
|
|
63743
|
+
type: "text",
|
|
63744
|
+
text: JSON.stringify({ nuclei_update: update, source: corpusSourceIsLive() ? "live nuclei-templates" : "bundled snapshot", cve_count: corpus.length })
|
|
63745
|
+
}
|
|
63746
|
+
]
|
|
63747
|
+
};
|
|
63748
|
+
});
|
|
63389
63749
|
server.registerTool("auto_poc", {
|
|
63390
63750
|
title: "Auto-PoC — generate a copy-paste-ready reproduction recipe",
|
|
63391
63751
|
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.",
|
|
@@ -64005,7 +64365,7 @@ ${statusLine}` : statusLine },
|
|
|
64005
64365
|
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.",
|
|
64006
64366
|
inputSchema: { path: string2().describe("Source file path (PHP)") }
|
|
64007
64367
|
}, async ({ path }) => {
|
|
64008
|
-
const code =
|
|
64368
|
+
const code = readFileSync31(path, "utf8");
|
|
64009
64369
|
const findings = detectRouteConfusion(code, path);
|
|
64010
64370
|
return {
|
|
64011
64371
|
content: [{
|
|
@@ -64019,7 +64379,7 @@ ${statusLine}` : statusLine },
|
|
|
64019
64379
|
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).",
|
|
64020
64380
|
inputSchema: { path: string2().describe("Source file path") }
|
|
64021
64381
|
}, async ({ path }) => {
|
|
64022
|
-
const code =
|
|
64382
|
+
const code = readFileSync31(path, "utf8");
|
|
64023
64383
|
const findings = detectComplexBugs(code, path);
|
|
64024
64384
|
return {
|
|
64025
64385
|
content: [{
|
|
@@ -64105,7 +64465,7 @@ ${statusLine}` : statusLine },
|
|
|
64105
64465
|
let lang = language;
|
|
64106
64466
|
if (path && !code) {
|
|
64107
64467
|
try {
|
|
64108
|
-
src =
|
|
64468
|
+
src = readFileSync31(path, "utf8");
|
|
64109
64469
|
} catch {
|
|
64110
64470
|
return { content: [{ type: "text", text: JSON.stringify({ error: `cannot read ${path}` }) }] };
|
|
64111
64471
|
}
|
|
@@ -64354,15 +64714,15 @@ async function serve() {
|
|
|
64354
64714
|
|
|
64355
64715
|
// src/index.ts
|
|
64356
64716
|
init_cli();
|
|
64357
|
-
import { readFileSync as
|
|
64358
|
-
import { join as
|
|
64359
|
-
import { fileURLToPath as
|
|
64360
|
-
var
|
|
64717
|
+
import { readFileSync as readFileSync35, existsSync as existsSync19 } from "node:fs";
|
|
64718
|
+
import { join as join32 } from "node:path";
|
|
64719
|
+
import { fileURLToPath as fileURLToPath21 } from "node:url";
|
|
64720
|
+
var ROOT14 = join32(fileURLToPath21(new URL(".", import.meta.url)), "..");
|
|
64361
64721
|
function readVersion() {
|
|
64362
64722
|
try {
|
|
64363
|
-
const p =
|
|
64364
|
-
if (
|
|
64365
|
-
return JSON.parse(
|
|
64723
|
+
const p = join32(ROOT14, "package.json");
|
|
64724
|
+
if (existsSync19(p))
|
|
64725
|
+
return JSON.parse(readFileSync35(p, "utf8")).version ?? "1.0.0";
|
|
64366
64726
|
} catch {}
|
|
64367
64727
|
return "1.0.0";
|
|
64368
64728
|
}
|