0sec-cli 0.17.0 → 0.21.4
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/{0sec.js → 0.js} +92 -79
- package/LICENSE +1 -1
- package/README.md +77 -37
- package/chunks/adapt-loop-IGBRQAXO.js +18 -0
- package/chunks/{adgraph-JLGA6RYI.js → adgraph-AUDQTBYA.js} +5 -5
- package/chunks/agent/skills/frameworks/entra-id.yaml +2 -2
- package/chunks/agent/skills/techniques/assumption-mining.yaml +2 -2
- package/chunks/agent/skills/techniques/cve-poc-adaptation.yaml +2 -2
- package/chunks/agent/skills/techniques/entra-attack-paths.yaml +1 -1
- package/chunks/agent/skills/techniques/kernel-weaponization.yaml +1 -1
- package/chunks/agent/skills/techniques/llm-prompt-injection.yaml +2 -2
- package/chunks/agent/skills/techniques/npm-ecosystem.yaml +1 -1
- package/chunks/agent/skills/techniques/poc-verification.yaml +1 -1
- package/chunks/agent/skills/techniques/seedless-depth-review.yaml +20 -38
- package/chunks/{artifact-scraper-GJEZMOHF.js → artifact-scraper-LNQJUORS.js} +6 -6
- package/chunks/{assumption-mining-BVMMUZHB.js → assumption-mining-4MJTP6H5.js} +24 -26
- package/chunks/{chunk-P6WKNFWX.js → chunk-2OQOQ2FZ.js} +8 -8
- package/chunks/{chunk-5G3ZXFBW.js → chunk-2WNCI664.js} +3 -3
- package/chunks/{chunk-HDWV7PGI.js → chunk-2WSXFFJZ.js} +4 -4
- package/chunks/{chunk-DW5UWPFY.js → chunk-4VGLO2YS.js} +6 -5
- package/chunks/{chunk-SNKTC4BP.js → chunk-5T6D5BVY.js} +88 -88
- package/chunks/{chunk-OEFNRYI2.js → chunk-6GHSR47F.js} +3 -6
- package/chunks/chunk-6YNKRUMC.js +4474 -0
- package/chunks/{chunk-O462Y7P2.js → chunk-ANDKY54G.js} +22317 -19616
- package/chunks/{chunk-53G27VPS.js → chunk-AZ7L3HFD.js} +7 -2
- package/chunks/{chunk-2SANI5RH.js → chunk-BACXRTQ4.js} +691 -318
- package/chunks/{chunk-SOG2U7B3.js → chunk-CAJJRUTV.js} +4 -4
- package/chunks/{chunk-57ZENEX2.js → chunk-CGHCEN7W.js} +3 -3
- package/chunks/{chunk-VGRDNSHA.js → chunk-CL5KAUM6.js} +17 -16
- package/chunks/{chunk-QOKTUOU2.js → chunk-CXKDWFNO.js} +6 -6
- package/chunks/{chunk-RWONANDA.js → chunk-DQTNI3KY.js} +5 -5
- package/chunks/{chunk-K26SZ37E.js → chunk-E2UOY5PJ.js} +288 -100
- package/chunks/{chunk-CLHCDHP4.js → chunk-ER3SUMYJ.js} +40 -18
- package/chunks/{chunk-IORC6MQX.js → chunk-FAH6V4QM.js} +31964 -32279
- package/chunks/{chunk-6LKRLK2R.js → chunk-FHC2B7LN.js} +3 -3
- package/chunks/{chunk-4Y4KQJXE.js → chunk-FWAYJ2IV.js} +16 -16
- package/chunks/{chunk-WVTBZEQO.js → chunk-G34QP2XW.js} +8 -8
- package/chunks/{chunk-MYVT64FN.js → chunk-GHWODZMR.js} +2 -2
- package/chunks/{chunk-F3WBKITT.js → chunk-GIQKESMN.js} +10 -10
- package/chunks/{chunk-2RMLOJVB.js → chunk-GVD6SJGH.js} +2 -2
- package/chunks/{chunk-RDZYQQLW.js → chunk-HBKCGJAV.js} +7 -7
- package/chunks/{chunk-SF4KZ4O3.js → chunk-HLFS6WV2.js} +2 -2
- package/chunks/chunk-HPQZHOIU.js +67 -0
- package/chunks/{chunk-3QFDYBZQ.js → chunk-IMGWPNQM.js} +231 -1308
- package/chunks/{chunk-3MOLBTLS.js → chunk-K2PWUPUI.js} +2 -2
- package/chunks/{chunk-MMLDQR4H.js → chunk-NDJU5ZZ7.js} +14 -14
- package/chunks/{chunk-H44E2CRN.js → chunk-NOPBXZUV.js} +3 -3
- package/chunks/{chunk-HE7LCA7G.js → chunk-O6SD4A36.js} +3 -3
- package/chunks/{chunk-SAFFWQW4.js → chunk-P6YG6TEZ.js} +6 -6
- package/chunks/{chunk-KKGE5RQE.js → chunk-PC6RCKQV.js} +198 -11
- package/chunks/{chunk-LP3HHYQU.js → chunk-PD2BBBKT.js} +2 -2
- package/chunks/{chunk-BKZFDZ23.js → chunk-QCUFBVIZ.js} +3 -3
- package/chunks/{chunk-KLTNTE2Z.js → chunk-QZVG3BG4.js} +14 -14
- package/chunks/{chunk-D6S3IIPG.js → chunk-RF5QGKLR.js} +9 -9
- package/chunks/{chunk-LOHTE223.js → chunk-SBMB4OL3.js} +9 -9
- package/chunks/{chunk-IOL7D5YV.js → chunk-SQCBHFWN.js} +3 -3
- package/chunks/{chunk-A6CLR72I.js → chunk-TF46UWFU.js} +3 -3
- package/chunks/chunk-TH2LW437.js +7829 -0
- package/chunks/chunk-TRH2PJSN.js +547 -0
- package/chunks/{chunk-RJWOYEOG.js → chunk-UEX7PFSE.js} +5 -5
- package/chunks/{chunk-VQG4FT5D.js → chunk-UFHN6RIU.js} +2 -2
- package/chunks/{chunk-WU6AFRAZ.js → chunk-V36HVTUL.js} +12 -12
- package/chunks/{chunk-IR537GON.js → chunk-VCSFCHAJ.js} +2 -2
- package/chunks/{chunk-YLMN3N25.js → chunk-VIT5ALXF.js} +3 -3
- package/chunks/{chunk-UJ4IK5PO.js → chunk-VOAXLO4A.js} +10 -10
- package/chunks/{chunk-UM3ZNQIM.js → chunk-W4JOXE4N.js} +100 -84
- package/chunks/{chunk-DN25OQQA.js → chunk-WF5W75WY.js} +25 -25
- package/chunks/{chunk-QKICO43A.js → chunk-WPQLBN4S.js} +5 -5
- package/chunks/{chunk-HT6P7RY3.js → chunk-WZISK5VC.js} +37 -35
- package/chunks/{chunk-QJQKHO7G.js → chunk-Y5H6E24H.js} +3 -3
- package/chunks/{chunk-KTQDLNSR.js → chunk-YA4PUM4H.js} +41 -41
- package/chunks/{chunk-47TQJWDH.js → chunk-YHWWF4QY.js} +9 -9
- package/chunks/{chunk-2CJ776PV.js → chunk-YPOA3W4O.js} +48 -39
- package/chunks/{chunk-7DQEV5QI.js → chunk-Z3IKZX3X.js} +4 -4
- package/chunks/codex-models-TYYV4JNN.js +15 -0
- package/chunks/{commands-U3AMV5ZU.js → commands-WF5RG4I2.js} +5620 -2513
- package/chunks/corpus-v1.json +2 -2
- package/chunks/data/appsec-archetypes.json +2 -2
- package/chunks/data/chromium-archetypes.json +1 -1
- package/chunks/data/freebsd-archetypes.json +1 -1
- package/chunks/data/kernel-archetypes.json +2 -2
- package/chunks/db-U3WQZVAO.js +16 -0
- package/chunks/{disclose-A6AEIEDA.js → disclose-67GZCDBO.js} +5 -5
- package/chunks/{dist-JR67XKYO.js → dist-ACC3DZUZ.js} +11 -5
- package/chunks/{dist-GL66KMUX.js → dist-EVTN3UTT.js} +6 -6
- package/chunks/{dist-FDKALV4R.js → dist-F6X62TQK.js} +290 -327
- package/chunks/dist-KEULE5IQ.js +21914 -0
- package/chunks/dist-XZB53PS5.js +53 -0
- package/chunks/eval-runner-SA6OUGHZ.js +26 -0
- package/chunks/example-manifest.json +2 -2
- package/chunks/{exploit-agent-XP23ISN7.js → exploit-agent-36Q7XQFP.js} +4 -4
- package/chunks/{exploit-autoclimb-E6T7RRSC.js → exploit-autoclimb-J4OTSTZ6.js} +6 -6
- package/chunks/{exploit-climb-2FAUP6XU.js → exploit-climb-PYEJDIC4.js} +12 -12
- package/chunks/fix-J2KBRJDV.js +12 -0
- package/chunks/{github-issues-MJ6OYOOU.js → github-issues-IGTTWM7V.js} +7 -7
- package/chunks/harness-GDUMKGSE.js +22 -0
- package/chunks/http-conformance-U5F6GKYG.js +11 -0
- package/chunks/http-sender-I5XFFY35.js +10 -0
- package/chunks/hunt-scan-UDJSCISU.js +36 -0
- package/chunks/{identity-6ZAIIWOR.js → identity-JTIVJSV7.js} +5 -5
- package/chunks/{kernel-primitive-TENE3R7T.js → kernel-primitive-F2IXUFAX.js} +6 -6
- package/chunks/{kernel-vm-runner-4F6QSNFY.js → kernel-vm-runner-276LHIOV.js} +6 -6
- package/chunks/memsafety-scan-NHUOGTEX.js +16 -0
- package/chunks/{native-loop-NTONUDP7.js → native-loop-3BSYVDUI.js} +17 -18
- package/chunks/{npm-detectors-KB5Y5ZFX.js → npm-detectors-VIYJXKFQ.js} +6 -6
- package/chunks/npm-dynamic-discovery-5J7FT3XM.js +13 -0
- package/chunks/orchestrate-DHBFRTSI.js +59 -0
- package/chunks/{pre-recon-cve-66EB6G4M.js → pre-recon-cve-X2K2P5YQ.js} +4 -4
- package/chunks/prepare-KYHGFWCJ.js +13 -0
- package/chunks/process-PNMC36JI.js +15 -0
- package/chunks/{replay-runner-RRR4E2A7.js → replay-runner-LK2XFIVG.js} +7 -7
- package/chunks/{run-ESNN4V5W.js → run-CBGE6DRQ.js} +2401 -1810
- package/chunks/{runtime-62ZQAH7H.js → runtime-PXO5G6UV.js} +11 -11
- package/chunks/runtime-XFWJTBUO.js +12 -0
- package/chunks/{scan-stream-FHI2FYZE.js → scan-stream-BMOCPKQX.js} +7 -7
- package/chunks/{scope-BI7BF4ZY.js → scope-NJHIDDTN.js} +4 -4
- package/chunks/{session-store-BCFQYDCE.js → session-store-46WBZM22.js} +6 -6
- package/chunks/source-files-REHOM44I.js +12 -0
- package/chunks/{specdrift-WCLH6TTQ.js → specdrift-AFS54WEJ.js} +5 -5
- package/chunks/token-KRWP5JYA.js +72 -0
- package/chunks/token-util-DWTL33S3.js +8 -0
- package/chunks/variant-candidates-UH2WC2HA.js +13 -0
- package/chunks/{web-recon-prepass-DPVCBRZA.js → web-recon-prepass-SFXU44SS.js} +9 -9
- package/dashboard/assets/desktop-BT7RkC4q.js +32 -0
- package/dashboard/assets/desktop-OaBI0E0e.css +1 -0
- package/dashboard/assets/{findings-page-CACW9nw2.js → findings-page-B4rwF6fZ.js} +2 -2
- package/dashboard/assets/{format-PoISqsES.js → format-LNQSSpn6.js} +1 -1
- package/dashboard/assets/live-page-DoNwpPAO.js +1 -0
- package/dashboard/assets/{meta-tile-CcskIV_o.js → meta-tile-BMtBC-Qq.js} +1 -1
- package/dashboard/assets/operations-CMFVrXEe.css +2 -0
- package/dashboard/assets/operations-app-ER0gg7GN.js +2 -0
- package/dashboard/assets/{operations-D8nUP5_m.js → operations-e2CGYKB1.js} +2 -2
- package/dashboard/assets/{overview-page-DTGS8dPo.js → overview-page-CmeWH17A.js} +1 -1
- package/dashboard/assets/{page-header-MFVvEtZW.js → page-header-CIJyycfz.js} +1 -1
- package/dashboard/assets/scans-page-CuhzWhHx.js +1 -0
- package/dashboard/assets/{table-BYS-nIVA.js → table-BgsSBdke.js} +1 -1
- package/dashboard/assets/{tabs-DivxbhQy.js → tabs-vn6v7Bk6.js} +1 -1
- package/dashboard/desktop.html +3 -3
- package/dashboard/index.html +3 -3
- package/package.json +11 -11
- package/chunks/adapt-loop-ECQG7454.js +0 -18
- package/chunks/appsec-catalog-CBWHGTEL.js +0 -24
- package/chunks/chunk-H2FFLZNK.js +0 -3
- package/chunks/chunk-QI233I24.js +0 -333
- package/chunks/chunk-RRMJC3ZE.js +0 -105
- package/chunks/chunk-SZJCPG2I.js +0 -110
- package/chunks/chunk-WKNNZVJS.js +0 -2798
- package/chunks/cost-ledger-ZCKMBJEN.js +0 -13
- package/chunks/db-26NGQFKO.js +0 -16
- package/chunks/eval-runner-DDLE5RQ3.js +0 -27
- package/chunks/fix-IG7LYXH3.js +0 -12
- package/chunks/harness-HWOYFKFY.js +0 -22
- package/chunks/http-conformance-DU66MZIU.js +0 -11
- package/chunks/http-sender-GWH2IYEA.js +0 -10
- package/chunks/hunt-scan-XPELSPQQ.js +0 -38
- package/chunks/memsafety-scan-J7SECV5W.js +0 -16
- package/chunks/npm-dynamic-discovery-AHROOZDB.js +0 -13
- package/chunks/orchestrate-ZUWAUWBC.js +0 -62
- package/chunks/pipeline-FCARFZU3.js +0 -14
- package/chunks/prepare-MYY743TK.js +0 -13
- package/chunks/process-3Q7QJIOZ.js +0 -13
- package/chunks/runtime-J7PLXZNM.js +0 -12
- package/chunks/source-files-PWRQR6LY.js +0 -12
- package/chunks/variant-candidates-6KM6F6MD.js +0 -13
- package/dashboard/assets/0sec-icon-66SreztZ.gif +0 -0
- package/dashboard/assets/desktop-CXTQonNm.js +0 -32
- package/dashboard/assets/desktop-NOekk4QS.css +0 -1
- package/dashboard/assets/live-page-DrgQqQK5.js +0 -1
- package/dashboard/assets/operations-BKE8T-vY.css +0 -2
- package/dashboard/assets/operations-app-CQQhG54n.js +0 -2
- package/dashboard/assets/scans-page-ChVtq8Us.js +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createRequire as
|
|
3
|
-
const require =
|
|
2
|
+
import { createRequire as __0CreateRequire } from "node:module";
|
|
3
|
+
const require = __0CreateRequire(import.meta.url);
|
|
4
4
|
var __create = Object.create;
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
6
6
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createRequire as
|
|
3
|
-
const require =
|
|
2
|
+
import { createRequire as __0CreateRequire } from "node:module";
|
|
3
|
+
const require = __0CreateRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
__export
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-VCSFCHAJ.js";
|
|
7
7
|
|
|
8
8
|
// node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
|
|
9
9
|
var external_exports = {};
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createRequire as
|
|
3
|
-
const require =
|
|
2
|
+
import { createRequire as __0CreateRequire } from "node:module";
|
|
3
|
+
const require = __0CreateRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
analyzeFindingForKnownMarkers,
|
|
6
6
|
detectKnownMarkers,
|
|
7
7
|
extractFileRefs,
|
|
8
8
|
redactSensitiveHeaders,
|
|
9
9
|
require_dist
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-W4JOXE4N.js";
|
|
11
11
|
import {
|
|
12
12
|
__toESM
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-VCSFCHAJ.js";
|
|
14
14
|
|
|
15
15
|
// packages/core/dist/disclose/screenshots.js
|
|
16
16
|
import { execFileSync } from "node:child_process";
|
|
@@ -384,7 +384,7 @@ function extractSiblingFix(finding, options) {
|
|
|
384
384
|
import { spawn } from "node:child_process";
|
|
385
385
|
var MAX_CAPTURE_BYTES = 1024 * 1024;
|
|
386
386
|
var DEFAULT_STEP_TIMEOUT_MS = 3e4;
|
|
387
|
-
var PERSONA_HEADER = "X-
|
|
387
|
+
var PERSONA_HEADER = "X-0-Persona";
|
|
388
388
|
var TRUNCATION_MARKER = "\n\u2026[truncated at 1MiB]";
|
|
389
389
|
var DEFAULT_RPS_PER_HOST = 2;
|
|
390
390
|
var MAX_REDIRECT_HOPS = 5;
|
|
@@ -1221,7 +1221,7 @@ function assembleBundleIndex(entries, options) {
|
|
|
1221
1221
|
lines.push(`| \`${id}\` | ${e.finding.severity} | ${titleCell} | ${e.patchStatus ?? "\u2014"} | ${e.behaviouralVerdict ?? "\u2014"} | ${redactReason(e)} | ${formatProvenance(e)} |`);
|
|
1222
1222
|
}
|
|
1223
1223
|
}
|
|
1224
|
-
lines.push("", "## Before filing each advisory", "", "1. Re-read the draft \u2014 the PoC and Patch Status sections are auto-populated from the scan but you should sanity-check against the current upstream HEAD.", "2. Verify the CVSS vector suggested by
|
|
1224
|
+
lines.push("", "## Before filing each advisory", "", "1. Re-read the draft \u2014 the PoC and Patch Status sections are auto-populated from the scan but you should sanity-check against the current upstream HEAD.", "2. Verify the CVSS vector suggested by 0 is still appropriate for your deployment model.", "3. Attach or replace screenshots in the PoC section as needed.", "4. File at https://github.com/<owner>/<repo>/security/advisories/new", "");
|
|
1225
1225
|
return lines.join("\n");
|
|
1226
1226
|
}
|
|
1227
1227
|
|
|
@@ -1376,7 +1376,7 @@ function generateWriteup(parsed, opts = {}) {
|
|
|
1376
1376
|
out.push(sanitizeWriteup(parts.join("\n\n")), "");
|
|
1377
1377
|
}
|
|
1378
1378
|
out.push("## Credits", "");
|
|
1379
|
-
out.push("Found by
|
|
1379
|
+
out.push("Found by 0.security's automated security-research tooling ([0.security](https://0.security)).", "");
|
|
1380
1380
|
const slug = slugify2(fm.short_name ? `${fm.package ?? ""}-${fm.short_name}` : title);
|
|
1381
1381
|
const filename = `${slug || "writeup"}-${dateStamp}.md`;
|
|
1382
1382
|
return {
|
|
@@ -1540,7 +1540,7 @@ var HIGH_IMPACT_CATEGORIES = /* @__PURE__ */ new Set([
|
|
|
1540
1540
|
// HS-vs-RS), and predictable RNG for secrets are direct key-leak / auth-bypass
|
|
1541
1541
|
// primitives, so the class is protected from score-only auto-drop.
|
|
1542
1542
|
"crypto-misuse",
|
|
1543
|
-
// AI-system adversarial classes — the core
|
|
1543
|
+
// AI-system adversarial classes — the core 0 "adversarial reliability"
|
|
1544
1544
|
// thesis (authorization-boundary break, unsafe tool use, data exfiltration,
|
|
1545
1545
|
// prompt hijack). A missed one of these is a disclosure-grade loss.
|
|
1546
1546
|
"prompt-injection",
|
|
@@ -1728,7 +1728,7 @@ function assembleEvidencePack(finding, opts = {}) {
|
|
|
1728
1728
|
function renderVendorNotificationMarkdown(draft) {
|
|
1729
1729
|
const out = [];
|
|
1730
1730
|
out.push(`# Vulnerability report: ${draft.title}`, "");
|
|
1731
|
-
out.push("> **DRAFT \u2014 NOT SENT.** Auto-assembled vendor-notification draft. An operator must review, fill in any `to be filled in` fields, and send it manually. Nothing here is transmitted to a vendor by
|
|
1731
|
+
out.push("> **DRAFT \u2014 NOT SENT.** Auto-assembled vendor-notification draft. An operator must review, fill in any `to be filled in` fields, and send it manually. Nothing here is transmitted to a vendor by 0. Embargo rules in `disclosure/AGENTS.md` apply.", "");
|
|
1732
1732
|
if (!draft.reproduced) {
|
|
1733
1733
|
out.push("> \u26A0\uFE0F This finding's PoC did **not** reproduce in an isolated env (`evidenceKind !== reproduced-poc`). Staged as an internal draft only \u2014 do not send to a vendor without a working PoC.", "");
|
|
1734
1734
|
}
|
|
@@ -1866,7 +1866,7 @@ function assembleReproducibilityManifest(finding, opts = {}) {
|
|
|
1866
1866
|
redactionsApplied.push("replay-verified-impact");
|
|
1867
1867
|
const target = opts.targetIdentifier ? redactManifestValue(opts.targetIdentifier) : extractTarget(finding);
|
|
1868
1868
|
const modelConfig = opts.modelConfig ? redactManifestValue(opts.modelConfig) : null;
|
|
1869
|
-
const toolVersion = opts.toolVersion ?? process.env["
|
|
1869
|
+
const toolVersion = opts.toolVersion ?? process.env["ZERO_VERSION"] ?? "unknown";
|
|
1870
1870
|
const timestamp = opts.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
1871
1871
|
const sanitizedTitle = redactManifestValue(finding.title);
|
|
1872
1872
|
const evidenceReq = finding.evidence?.request ?? null;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createRequire as
|
|
3
|
-
const require =
|
|
2
|
+
import { createRequire as __0CreateRequire } from "node:module";
|
|
3
|
+
const require = __0CreateRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
__commonJS,
|
|
6
6
|
__require
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-VCSFCHAJ.js";
|
|
8
8
|
|
|
9
9
|
// node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/dist/nodes/identity.js
|
|
10
10
|
var require_identity = __commonJS({
|
|
@@ -7333,66 +7333,6 @@ var require_dist = __commonJS({
|
|
|
7333
7333
|
}
|
|
7334
7334
|
});
|
|
7335
7335
|
|
|
7336
|
-
// packages/core/dist/disclose/known-marker.js
|
|
7337
|
-
var SOURCE_MARKER_RE = /\b(TODO|FIXME|XXX|HACK)\b(?:[(:]\s*(.*?)\s*[):])?|(\bknown[ -](?:limitation|issue)s?\b|\bdocumented[ -]limitation\b)/gi;
|
|
7338
|
-
function hasKnownMarkerText(source) {
|
|
7339
|
-
SOURCE_MARKER_RE.lastIndex = 0;
|
|
7340
|
-
const matched = SOURCE_MARKER_RE.test(source);
|
|
7341
|
-
SOURCE_MARKER_RE.lastIndex = 0;
|
|
7342
|
-
return matched;
|
|
7343
|
-
}
|
|
7344
|
-
function detectKnownMarkers(source, filePath) {
|
|
7345
|
-
const lines = source.split("\n");
|
|
7346
|
-
const markers = [];
|
|
7347
|
-
for (let i = 0; i < lines.length; i++) {
|
|
7348
|
-
const line = lines[i];
|
|
7349
|
-
SOURCE_MARKER_RE.lastIndex = 0;
|
|
7350
|
-
let match;
|
|
7351
|
-
while ((match = SOURCE_MARKER_RE.exec(line)) !== null) {
|
|
7352
|
-
const tag = match[1];
|
|
7353
|
-
const phrase = match[3];
|
|
7354
|
-
const markerText = tag ?? phrase ?? match[0];
|
|
7355
|
-
const contextLines = [];
|
|
7356
|
-
if (i > 0)
|
|
7357
|
-
contextLines.push(lines[i - 1]);
|
|
7358
|
-
contextLines.push(line);
|
|
7359
|
-
if (i < lines.length - 1)
|
|
7360
|
-
contextLines.push(lines[i + 1]);
|
|
7361
|
-
markers.push({
|
|
7362
|
-
marker: markerText.toLowerCase(),
|
|
7363
|
-
line: line.length > 200 ? line.slice(0, 100) + "..." + line.slice(line.length - 97) : line,
|
|
7364
|
-
lineNumber: i + 1,
|
|
7365
|
-
sourcePath: filePath,
|
|
7366
|
-
context: contextLines.join("\n")
|
|
7367
|
-
});
|
|
7368
|
-
}
|
|
7369
|
-
}
|
|
7370
|
-
return {
|
|
7371
|
-
hasKnownMarker: markers.length > 0,
|
|
7372
|
-
markers
|
|
7373
|
-
};
|
|
7374
|
-
}
|
|
7375
|
-
function analyzeFindingForKnownMarkers(finding) {
|
|
7376
|
-
const texts = [];
|
|
7377
|
-
if (finding.evidence?.analysis)
|
|
7378
|
-
texts.push(finding.evidence.analysis);
|
|
7379
|
-
if (finding.description)
|
|
7380
|
-
texts.push(finding.description);
|
|
7381
|
-
if (finding.evidence?.request)
|
|
7382
|
-
texts.push(finding.evidence.request);
|
|
7383
|
-
if (finding.evidence?.response)
|
|
7384
|
-
texts.push(finding.evidence.response);
|
|
7385
|
-
const allMarkers = [];
|
|
7386
|
-
for (const text of texts) {
|
|
7387
|
-
const signal = detectKnownMarkers(text);
|
|
7388
|
-
allMarkers.push(...signal.markers);
|
|
7389
|
-
}
|
|
7390
|
-
return {
|
|
7391
|
-
hasKnownMarker: allMarkers.length > 0,
|
|
7392
|
-
markers: allMarkers
|
|
7393
|
-
};
|
|
7394
|
-
}
|
|
7395
|
-
|
|
7396
7336
|
// packages/core/dist/disclose/cwe.js
|
|
7397
7337
|
var CWE_MAP = {
|
|
7398
7338
|
// LLM / agent
|
|
@@ -7666,6 +7606,8 @@ function metricsForReachability(tier) {
|
|
|
7666
7606
|
switch (tier) {
|
|
7667
7607
|
case "remote-unauth":
|
|
7668
7608
|
return { av: "N", pr: "N", ui: "N" };
|
|
7609
|
+
case "remote-auth":
|
|
7610
|
+
return { av: "N", pr: "L", ui: "N" };
|
|
7669
7611
|
case "proximity-rf":
|
|
7670
7612
|
return { av: "A", pr: "N", ui: "N" };
|
|
7671
7613
|
case "local-unpriv":
|
|
@@ -8382,6 +8324,8 @@ function cvss4MetricsForReachability(tier) {
|
|
|
8382
8324
|
switch (tier) {
|
|
8383
8325
|
case "remote-unauth":
|
|
8384
8326
|
return { AV: "N", AT: "N", PR: "N", UI: "N" };
|
|
8327
|
+
case "remote-auth":
|
|
8328
|
+
return { AV: "N", AT: "N", PR: "L", UI: "N" };
|
|
8385
8329
|
case "proximity-rf":
|
|
8386
8330
|
return { AV: "A", AT: "N", PR: "N", UI: "N" };
|
|
8387
8331
|
case "local-unpriv":
|
|
@@ -8690,17 +8634,31 @@ var EmptyPocError = class extends Error {
|
|
|
8690
8634
|
};
|
|
8691
8635
|
var SENSITIVE_HEADER_NAMES = /* @__PURE__ */ new Set([
|
|
8692
8636
|
"authorization",
|
|
8637
|
+
"proxy-authorization",
|
|
8693
8638
|
"cookie",
|
|
8694
8639
|
"set-cookie",
|
|
8695
8640
|
"x-auth-token",
|
|
8696
8641
|
"x-api-key",
|
|
8697
|
-
"x-csrf-token"
|
|
8642
|
+
"x-csrf-token",
|
|
8643
|
+
"x-xsrf-token"
|
|
8698
8644
|
]);
|
|
8699
8645
|
var AWS_KEY_RE = /\bAKIA[0-9A-Z]{16}\b/g;
|
|
8700
8646
|
var JWT_RE = /\b[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+={0,2}\b/g;
|
|
8701
8647
|
var INLINE_BEARER_RE = /\b(Bearer)\s+([^\s"'`]+)/gi;
|
|
8702
8648
|
var INLINE_CURL_HEADER_RE = /(-H|--header)(\s+|=)(["']?)([A-Za-z][A-Za-z0-9-]*)\s*:\s*([^"'\n]*)\3/gi;
|
|
8703
8649
|
function redactSensitiveHeaders(text) {
|
|
8650
|
+
if (!text)
|
|
8651
|
+
return text;
|
|
8652
|
+
let out = redactAuthHeaders(text);
|
|
8653
|
+
out = out.replace(AWS_KEY_RE, "<REDACTED-AWS-KEY>");
|
|
8654
|
+
out = out.replace(JWT_RE, (match) => {
|
|
8655
|
+
if (match.length < 80)
|
|
8656
|
+
return match;
|
|
8657
|
+
return "<REDACTED-JWT>";
|
|
8658
|
+
});
|
|
8659
|
+
return out;
|
|
8660
|
+
}
|
|
8661
|
+
function redactAuthHeaders(text) {
|
|
8704
8662
|
if (!text)
|
|
8705
8663
|
return text;
|
|
8706
8664
|
const lines = text.split("\n");
|
|
@@ -8717,19 +8675,14 @@ function redactSensitiveHeaders(text) {
|
|
|
8717
8675
|
return match;
|
|
8718
8676
|
return `${flag}${sep}${quote}${name}: <REDACTED-${name}>${quote}`;
|
|
8719
8677
|
});
|
|
8720
|
-
|
|
8721
|
-
out = out.replace(AWS_KEY_RE, "<REDACTED-AWS-KEY>");
|
|
8722
|
-
out = out.replace(JWT_RE, (match) => {
|
|
8723
|
-
if (match.length < 80)
|
|
8724
|
-
return match;
|
|
8725
|
-
return "<REDACTED-JWT>";
|
|
8726
|
-
});
|
|
8727
|
-
return out;
|
|
8678
|
+
return out.replace(INLINE_BEARER_RE, "$1 <REDACTED-Bearer>");
|
|
8728
8679
|
}
|
|
8729
8680
|
function reachabilityLabel(tier) {
|
|
8730
8681
|
switch (tier) {
|
|
8731
8682
|
case "remote-unauth":
|
|
8732
8683
|
return "remote, unauthenticated \u2014 reachable over the network with no credentials";
|
|
8684
|
+
case "remote-auth":
|
|
8685
|
+
return "remote, authenticated \u2014 requires an account or contributor access";
|
|
8733
8686
|
case "proximity-rf":
|
|
8734
8687
|
return "RF/physical proximity \u2014 attacker must be within radio range (NFC/BLE/Wi-Fi)";
|
|
8735
8688
|
case "local-unpriv":
|
|
@@ -8748,6 +8701,8 @@ function weaponizabilityLabel(w) {
|
|
|
8748
8701
|
return "remote code execution";
|
|
8749
8702
|
case "lpe-to-root":
|
|
8750
8703
|
return "local privilege escalation to root/SYSTEM";
|
|
8704
|
+
case "integrity-tampering":
|
|
8705
|
+
return "workflow integrity manipulation";
|
|
8751
8706
|
case "info-leak":
|
|
8752
8707
|
return "information disclosure";
|
|
8753
8708
|
case "dos-crash":
|
|
@@ -8805,9 +8760,9 @@ function renderAdvisoryMarkdown(finding, ctx = {}) {
|
|
|
8805
8760
|
} else if (ctx.target) {
|
|
8806
8761
|
affectedLine = `\`${ctx.target}\`${ctx.targetRef ? ` at \`${ctx.targetRef}\`` : ""}${ctx.commitHash ? ` (commit \`${ctx.commitHash.slice(0, 12)}\`)` : ""}`;
|
|
8807
8762
|
} else {
|
|
8808
|
-
affectedLine = "_Pass `--repo <path>` to
|
|
8763
|
+
affectedLine = "_Pass `--repo <path>` to `@0/cli disclose` to auto-detect the affected version range from git tags._";
|
|
8809
8764
|
}
|
|
8810
|
-
const cvssSource = cvss.source === "finding" ? "populated on the finding by
|
|
8765
|
+
const cvssSource = cvss.source === "finding" ? "populated on the finding by 0" : cvss.source === "impact-assessment" ? "exploitability metrics derived from 0's reachability assessment; impact from category \u2014 verify against your deployment" : "heuristic from category + severity \u2014 override in the GHSA editor if the operator disagrees";
|
|
8811
8766
|
const remediation = finding.remediation;
|
|
8812
8767
|
const suggestedFixParts = [];
|
|
8813
8768
|
if (remediation?.summary)
|
|
@@ -8832,7 +8787,7 @@ ${remediation.codeExample.after}
|
|
|
8832
8787
|
\`\`\``);
|
|
8833
8788
|
} else if (ctx.siblingFix) {
|
|
8834
8789
|
const ref = `${ctx.siblingFix.fileRef.file}${ctx.siblingFix.fileRef.line ? `:${ctx.siblingFix.fileRef.line}` : ""}`;
|
|
8835
|
-
suggestedFixParts.push(`**Correct pattern already present in the repo at \`${ref}\`** *(extracted by
|
|
8790
|
+
suggestedFixParts.push(`**Correct pattern already present in the repo at \`${ref}\`** *(extracted by 0):*
|
|
8836
8791
|
|
|
8837
8792
|
\`\`\`${ctx.siblingFix.language}
|
|
8838
8793
|
${ctx.siblingFix.snippet}
|
|
@@ -8864,7 +8819,7 @@ ${ctx.siblingFix.snippet}
|
|
|
8864
8819
|
if (ctx.osecVersion || ctx.scanId) {
|
|
8865
8820
|
const bits = [];
|
|
8866
8821
|
if (ctx.osecVersion)
|
|
8867
|
-
bits.push(`
|
|
8822
|
+
bits.push(`0 \`${ctx.osecVersion}\``);
|
|
8868
8823
|
if (ctx.scanId)
|
|
8869
8824
|
bits.push(`scan \`${ctx.scanId.slice(0, 8)}\``);
|
|
8870
8825
|
const canaryPositive = ctx.patchStatus?.status === "still-vulnerable";
|
|
@@ -8916,7 +8871,7 @@ ${ctx.siblingFix.snippet}
|
|
|
8916
8871
|
if (ctx.patchStatus) {
|
|
8917
8872
|
out.push(formatPatchStatusSection(ctx.patchStatus), "");
|
|
8918
8873
|
} else {
|
|
8919
|
-
out.push("_Pass `--repo <path>` to
|
|
8874
|
+
out.push("_Pass `--repo <path>` to `@0/cli disclose` to auto-verify this against the target's current HEAD or a specific tag._", "");
|
|
8920
8875
|
}
|
|
8921
8876
|
if (ctx.pocExecution) {
|
|
8922
8877
|
const verdict = ctx.pocExecution.overallVerdict === "exploit_still_works" ? "**Behavioural check: exploit still reproducible.**" : ctx.pocExecution.overallVerdict === "exploit_broken" ? "**Behavioural check: exploit no longer reproducible.**" : "**Behavioural check: could not run.**";
|
|
@@ -8924,7 +8879,7 @@ ${ctx.siblingFix.snippet}
|
|
|
8924
8879
|
out.push(`> Verdict: \`${ctx.pocExecution.overallVerdict}\` (${ctx.pocExecution.steps.length} step${ctx.pocExecution.steps.length === 1 ? "" : "s"} executed).`, "");
|
|
8925
8880
|
}
|
|
8926
8881
|
out.push("## Credits", "");
|
|
8927
|
-
out.push("Discovered by **
|
|
8882
|
+
out.push("Discovered by **0.security**, the 0.security AI-assisted security engine ([0.security](https://0.security)).", "", "Reporter: _(your github handle)_", "");
|
|
8928
8883
|
return {
|
|
8929
8884
|
filename,
|
|
8930
8885
|
markdown: out.join("\n").replace(/\n{3,}/g, "\n\n"),
|
|
@@ -9012,7 +8967,7 @@ ${remediation.codeExample.after}
|
|
|
9012
8967
|
\`\`\``);
|
|
9013
8968
|
} else if (ctx.siblingFix) {
|
|
9014
8969
|
const ref = `${ctx.siblingFix.fileRef.file}${ctx.siblingFix.fileRef.line ? `:${ctx.siblingFix.fileRef.line}` : ""}`;
|
|
9015
|
-
parts.push(`**Correct pattern already present in the repo at \`${ref}\`** *(extracted by
|
|
8970
|
+
parts.push(`**Correct pattern already present in the repo at \`${ref}\`** *(extracted by 0):*
|
|
9016
8971
|
|
|
9017
8972
|
\`\`\`${ctx.siblingFix.language}
|
|
9018
8973
|
${ctx.siblingFix.snippet}
|
|
@@ -9275,7 +9230,7 @@ _${cvssSourceLabel(parts.cvss)}_` },
|
|
|
9275
9230
|
}
|
|
9276
9231
|
};
|
|
9277
9232
|
function cvssSourceLabel(cvss) {
|
|
9278
|
-
return cvss.source === "finding" ? "CVSS source: populated on the finding by
|
|
9233
|
+
return cvss.source === "finding" ? "CVSS source: populated on the finding by 0." : cvss.source === "impact-assessment" ? "CVSS source: exploitability derived from 0's reachability assessment; impact from category \u2014 verify against your deployment." : "CVSS source: heuristic from category + severity \u2014 verify before submission.";
|
|
9279
9234
|
}
|
|
9280
9235
|
var TEMPLATE_REGISTRY = {
|
|
9281
9236
|
hackerone: HACKERONE_TEMPLATE,
|
|
@@ -9299,11 +9254,68 @@ function renderPlatformReport(finding, platform, ctx = {}) {
|
|
|
9299
9254
|
return reportTemplate(platform).render(finding, ctx);
|
|
9300
9255
|
}
|
|
9301
9256
|
|
|
9257
|
+
// packages/core/dist/disclose/known-marker.js
|
|
9258
|
+
var SOURCE_MARKER_RE = /\b(TODO|FIXME|XXX|HACK)\b(?:[(:]\s*(.*?)\s*[):])?|(\bknown[ -](?:limitation|issue)s?\b|\bdocumented[ -]limitation\b)/gi;
|
|
9259
|
+
function hasKnownMarkerText(source) {
|
|
9260
|
+
SOURCE_MARKER_RE.lastIndex = 0;
|
|
9261
|
+
const matched = SOURCE_MARKER_RE.test(source);
|
|
9262
|
+
SOURCE_MARKER_RE.lastIndex = 0;
|
|
9263
|
+
return matched;
|
|
9264
|
+
}
|
|
9265
|
+
function detectKnownMarkers(source, filePath) {
|
|
9266
|
+
const lines = source.split("\n");
|
|
9267
|
+
const markers = [];
|
|
9268
|
+
for (let i = 0; i < lines.length; i++) {
|
|
9269
|
+
const line = lines[i];
|
|
9270
|
+
SOURCE_MARKER_RE.lastIndex = 0;
|
|
9271
|
+
let match;
|
|
9272
|
+
while ((match = SOURCE_MARKER_RE.exec(line)) !== null) {
|
|
9273
|
+
const tag = match[1];
|
|
9274
|
+
const phrase = match[3];
|
|
9275
|
+
const markerText = tag ?? phrase ?? match[0];
|
|
9276
|
+
const contextLines = [];
|
|
9277
|
+
if (i > 0)
|
|
9278
|
+
contextLines.push(lines[i - 1]);
|
|
9279
|
+
contextLines.push(line);
|
|
9280
|
+
if (i < lines.length - 1)
|
|
9281
|
+
contextLines.push(lines[i + 1]);
|
|
9282
|
+
markers.push({
|
|
9283
|
+
marker: markerText.toLowerCase(),
|
|
9284
|
+
line: line.length > 200 ? line.slice(0, 100) + "..." + line.slice(line.length - 97) : line,
|
|
9285
|
+
lineNumber: i + 1,
|
|
9286
|
+
sourcePath: filePath,
|
|
9287
|
+
context: contextLines.join("\n")
|
|
9288
|
+
});
|
|
9289
|
+
}
|
|
9290
|
+
}
|
|
9291
|
+
return {
|
|
9292
|
+
hasKnownMarker: markers.length > 0,
|
|
9293
|
+
markers
|
|
9294
|
+
};
|
|
9295
|
+
}
|
|
9296
|
+
function analyzeFindingForKnownMarkers(finding) {
|
|
9297
|
+
const texts = [];
|
|
9298
|
+
if (finding.evidence?.analysis)
|
|
9299
|
+
texts.push(finding.evidence.analysis);
|
|
9300
|
+
if (finding.description)
|
|
9301
|
+
texts.push(finding.description);
|
|
9302
|
+
if (finding.evidence?.request)
|
|
9303
|
+
texts.push(finding.evidence.request);
|
|
9304
|
+
if (finding.evidence?.response)
|
|
9305
|
+
texts.push(finding.evidence.response);
|
|
9306
|
+
const allMarkers = [];
|
|
9307
|
+
for (const text of texts) {
|
|
9308
|
+
const signal = detectKnownMarkers(text);
|
|
9309
|
+
allMarkers.push(...signal.markers);
|
|
9310
|
+
}
|
|
9311
|
+
return {
|
|
9312
|
+
hasKnownMarker: allMarkers.length > 0,
|
|
9313
|
+
markers: allMarkers
|
|
9314
|
+
};
|
|
9315
|
+
}
|
|
9316
|
+
|
|
9302
9317
|
export {
|
|
9303
9318
|
require_dist,
|
|
9304
|
-
hasKnownMarkerText,
|
|
9305
|
-
detectKnownMarkers,
|
|
9306
|
-
analyzeFindingForKnownMarkers,
|
|
9307
9319
|
suggestCwesForCategory,
|
|
9308
9320
|
formatCweSection,
|
|
9309
9321
|
suggestCvss,
|
|
@@ -9322,8 +9334,12 @@ export {
|
|
|
9322
9334
|
formatVersionRangeLine,
|
|
9323
9335
|
EmptyPocError,
|
|
9324
9336
|
redactSensitiveHeaders,
|
|
9337
|
+
redactAuthHeaders,
|
|
9325
9338
|
renderAdvisoryMarkdown,
|
|
9326
9339
|
REPORT_PLATFORMS,
|
|
9327
9340
|
reportTemplate,
|
|
9328
|
-
renderPlatformReport
|
|
9341
|
+
renderPlatformReport,
|
|
9342
|
+
hasKnownMarkerText,
|
|
9343
|
+
detectKnownMarkers,
|
|
9344
|
+
analyzeFindingForKnownMarkers
|
|
9329
9345
|
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createRequire as
|
|
3
|
-
const require =
|
|
2
|
+
import { createRequire as __0CreateRequire } from "node:module";
|
|
3
|
+
const require = __0CreateRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
allowlistedChildEnv
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-QZVG3BG4.js";
|
|
7
7
|
import {
|
|
8
8
|
VERSION
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-PC6RCKQV.js";
|
|
10
10
|
|
|
11
11
|
// packages/core/dist/verify/replay-runner.js
|
|
12
12
|
import { spawn } from "node:child_process";
|
|
@@ -52,7 +52,7 @@ var LocalShellRunner = class {
|
|
|
52
52
|
// child must not inherit the harness's provider/cloud credentials.
|
|
53
53
|
// Build from the allowlist (PATH/HOME/TMPDIR + target-auth vars a
|
|
54
54
|
// reproduction legitimately needs) rather than copying process.env.
|
|
55
|
-
env: allowlistedChildEnv({ "
|
|
55
|
+
env: allowlistedChildEnv({ "ZERO_VERIFY": "1" }),
|
|
56
56
|
stdio: ["ignore", "pipe", "pipe"],
|
|
57
57
|
// On POSIX, isolate the shell and all descendants into a process
|
|
58
58
|
// group so a timeout cannot leave a grandchild holding stdout open.
|
|
@@ -138,7 +138,7 @@ function resolveStepCwd(cwd, runDir) {
|
|
|
138
138
|
}
|
|
139
139
|
var DEFAULT_DOCKER_SHELL_IMAGE = "alpine:3.20";
|
|
140
140
|
var DEFAULT_DOCKER_HTTP_IMAGE = "curlimages/curl:8.12.1";
|
|
141
|
-
var DOCKER_HTTP_STATUS_MARKER = "\
|
|
141
|
+
var DOCKER_HTTP_STATUS_MARKER = "\n__ZERO_HTTP_STATUS__:";
|
|
142
142
|
var CONTAINER_ID_RE = /^[a-f0-9]{12,64}$/i;
|
|
143
143
|
var DOCKER_NETWORK_RE = /^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/;
|
|
144
144
|
var DockerRunner = class {
|
|
@@ -176,7 +176,7 @@ var DockerRunner = class {
|
|
|
176
176
|
return failedStep(step, startedAt, command);
|
|
177
177
|
}
|
|
178
178
|
const safeStepId = step.id.replace(/[^a-zA-Z0-9_.-]/g, "_").slice(0, 64) || "step";
|
|
179
|
-
const cidPath = join(ctx.runDir, `.
|
|
179
|
+
const cidPath = join(ctx.runDir, `.0-docker-${safeStepId}-${randomUUID()}.cid`);
|
|
180
180
|
const args = this.dockerRunArgs(command, ctx.runDir, cidPath);
|
|
181
181
|
const result = await runDockerCommand({
|
|
182
182
|
dockerBinary: this.dockerBinary,
|
|
@@ -382,7 +382,7 @@ async function runDockerCommand(args) {
|
|
|
382
382
|
try {
|
|
383
383
|
child = spawn(args.dockerBinary, args.args, {
|
|
384
384
|
cwd: args.runDir,
|
|
385
|
-
env: allowlistedChildEnv({ "
|
|
385
|
+
env: allowlistedChildEnv({ "ZERO_VERIFY": "1" }),
|
|
386
386
|
stdio: ["ignore", "pipe", "pipe"],
|
|
387
387
|
detached: nodePlatform !== "win32"
|
|
388
388
|
});
|
|
@@ -444,7 +444,7 @@ function runDockerControl(dockerBinary, args, cwd) {
|
|
|
444
444
|
try {
|
|
445
445
|
child = spawn(dockerBinary, args, {
|
|
446
446
|
cwd,
|
|
447
|
-
env: allowlistedChildEnv({ "
|
|
447
|
+
env: allowlistedChildEnv({ "ZERO_VERIFY": "1" }),
|
|
448
448
|
stdio: "ignore",
|
|
449
449
|
detached: nodePlatform !== "win32"
|
|
450
450
|
});
|
|
@@ -483,9 +483,9 @@ var QemuRunner = class {
|
|
|
483
483
|
memoryMb;
|
|
484
484
|
cpus;
|
|
485
485
|
constructor(options = {}) {
|
|
486
|
-
this.qemuBinary = options.qemuBinary ?? process.env["
|
|
487
|
-
this.kernelImage = options.kernelImage ?? process.env["
|
|
488
|
-
this.busyboxPath = options.busyboxPath ?? process.env["
|
|
486
|
+
this.qemuBinary = options.qemuBinary ?? process.env["ZERO_REPLAY_QEMU_BINARY"]?.trim() ?? (nodeArch === "arm64" ? "qemu-system-aarch64" : "qemu-system-x86_64");
|
|
487
|
+
this.kernelImage = options.kernelImage ?? process.env["ZERO_REPLAY_QEMU_KERNEL"]?.trim() ?? "";
|
|
488
|
+
this.busyboxPath = options.busyboxPath ?? process.env["ZERO_REPLAY_QEMU_BUSYBOX"]?.trim() ?? "";
|
|
489
489
|
this.memoryMb = options.memoryMb ?? 512;
|
|
490
490
|
this.cpus = options.cpus ?? 1;
|
|
491
491
|
if (!this.qemuBinary || !Number.isInteger(this.memoryMb) || this.memoryMb < 128 || !Number.isInteger(this.cpus) || this.cpus < 1) {
|
|
@@ -495,7 +495,7 @@ var QemuRunner = class {
|
|
|
495
495
|
async exec(step, ctx) {
|
|
496
496
|
const startedAt = Date.now();
|
|
497
497
|
if (!this.kernelImage || !this.busyboxPath) {
|
|
498
|
-
return failedStep(step, startedAt, "QEMU replay requires kernelImage and busyboxPath (or
|
|
498
|
+
return failedStep(step, startedAt, "QEMU replay requires kernelImage and busyboxPath (or ZERO_REPLAY_QEMU_KERNEL and ZERO_REPLAY_QEMU_BUSYBOX)");
|
|
499
499
|
}
|
|
500
500
|
if (!existsSync(this.kernelImage) || !statSync(this.kernelImage).isFile()) {
|
|
501
501
|
return failedStep(step, startedAt, `QEMU kernel image is not a file: ${this.kernelImage}`);
|
|
@@ -511,7 +511,7 @@ var QemuRunner = class {
|
|
|
511
511
|
return failedStep(step, startedAt, "QEMU replay refuses an absolute step cwd");
|
|
512
512
|
}
|
|
513
513
|
const safeStepId = step.id.replace(/[^a-zA-Z0-9_.-]/g, "_").slice(0, 64) || "step";
|
|
514
|
-
const workspaceName = `.
|
|
514
|
+
const workspaceName = `.0-qemu-${safeStepId}-${randomUUID()}`;
|
|
515
515
|
const workspace = join(ctx.runDir, workspaceName);
|
|
516
516
|
mkdirSync(workspace, { recursive: true });
|
|
517
517
|
writeFileSync(join(workspace, "step.sh"), step.action.cmd, "utf8");
|
|
@@ -567,7 +567,7 @@ ${qemu.stdoutFull}` : "";
|
|
|
567
567
|
"-append",
|
|
568
568
|
"console=ttyS0 rdinit=/init panic=-1",
|
|
569
569
|
"-virtfs",
|
|
570
|
-
`local,path=${resolve(runDir)},mount_tag=
|
|
570
|
+
`local,path=${resolve(runDir)},mount_tag=0-replay,security_model=none,id=osecshare`,
|
|
571
571
|
"-net",
|
|
572
572
|
"none",
|
|
573
573
|
"-sandbox",
|
|
@@ -577,11 +577,11 @@ ${qemu.stdoutFull}` : "";
|
|
|
577
577
|
};
|
|
578
578
|
function qemuGuestWorkingDirectory(cwd) {
|
|
579
579
|
if (!cwd)
|
|
580
|
-
return "/mnt/
|
|
580
|
+
return "/mnt/0";
|
|
581
581
|
if (isAbsolute(cwd))
|
|
582
582
|
return void 0;
|
|
583
583
|
const relative = resolve("/", cwd).slice(1);
|
|
584
|
-
return relative ? `/mnt/
|
|
584
|
+
return relative ? `/mnt/0/${relative}` : "/mnt/0";
|
|
585
585
|
}
|
|
586
586
|
function buildQemuInitramfs(args) {
|
|
587
587
|
const empty = Buffer.alloc(0);
|
|
@@ -590,7 +590,7 @@ function buildQemuInitramfs(args) {
|
|
|
590
590
|
{ name: "bin", mode: 16877, body: empty },
|
|
591
591
|
{ name: "dev", mode: 16877, body: empty },
|
|
592
592
|
{ name: "mnt", mode: 16877, body: empty },
|
|
593
|
-
{ name: "mnt/
|
|
593
|
+
{ name: "mnt/0", mode: 16877, body: empty },
|
|
594
594
|
{ name: "proc", mode: 16877, body: empty },
|
|
595
595
|
{ name: "sys", mode: 16877, body: empty },
|
|
596
596
|
{ name: "tmp", mode: 16877, body: empty },
|
|
@@ -602,7 +602,7 @@ function buildQemuInitramfs(args) {
|
|
|
602
602
|
appendNewcEntry(chunks, entries[index], index + 1);
|
|
603
603
|
}
|
|
604
604
|
appendNewcEntry(chunks, { name: "TRAILER!!!", mode: 0, body: empty }, 0);
|
|
605
|
-
const initrdPath = join(args.runDir, `.
|
|
605
|
+
const initrdPath = join(args.runDir, `.0-qemu-initrd-${randomUUID()}.cpio.gz`);
|
|
606
606
|
writeFileSync(initrdPath, gzipSync(Buffer.concat(chunks)));
|
|
607
607
|
return initrdPath;
|
|
608
608
|
}
|
|
@@ -634,19 +634,19 @@ function appendNewcEntry(chunks, entry, inode) {
|
|
|
634
634
|
chunks.push(Buffer.alloc(bodyPadding));
|
|
635
635
|
}
|
|
636
636
|
function renderQemuInit(workspaceName, guestCwd) {
|
|
637
|
-
const workspace = `/mnt/
|
|
637
|
+
const workspace = `/mnt/0/${workspaceName}`;
|
|
638
638
|
const step = `${workspace}/step.sh`;
|
|
639
639
|
const stdout = `${workspace}/stdout.log`;
|
|
640
640
|
const stderr = `${workspace}/stderr.log`;
|
|
641
641
|
const exitCode = `${workspace}/exit-code`;
|
|
642
642
|
return [
|
|
643
643
|
"#!/bin/busybox sh",
|
|
644
|
-
"/bin/busybox mkdir -p /proc /sys /dev /tmp /mnt/
|
|
644
|
+
"/bin/busybox mkdir -p /proc /sys /dev /tmp /mnt/0",
|
|
645
645
|
"/bin/busybox mount -t proc proc /proc",
|
|
646
646
|
"/bin/busybox mount -t sysfs sysfs /sys",
|
|
647
647
|
"/bin/busybox mount -t devtmpfs devtmpfs /dev 2>/dev/null || true",
|
|
648
|
-
"if ! /bin/busybox mount -t 9p -o trans=virtio,version=9p2000.L
|
|
649
|
-
' echo "
|
|
648
|
+
"if ! /bin/busybox mount -t 9p -o trans=virtio,version=9p2000.L 0-replay /mnt/0; then",
|
|
649
|
+
' echo "__ZERO_QEMU_MOUNT_FAILED__"',
|
|
650
650
|
" /bin/busybox poweroff -f",
|
|
651
651
|
"fi",
|
|
652
652
|
`(
|
|
@@ -708,7 +708,7 @@ function runQemuCommand(args) {
|
|
|
708
708
|
try {
|
|
709
709
|
child = spawn(args.qemuBinary, args.args, {
|
|
710
710
|
cwd: args.runDir,
|
|
711
|
-
env: allowlistedChildEnv({ "
|
|
711
|
+
env: allowlistedChildEnv({ "ZERO_VERIFY": "1" }),
|
|
712
712
|
stdio: ["ignore", "pipe", "pipe"],
|
|
713
713
|
detached: nodePlatform !== "win32"
|
|
714
714
|
});
|
|
@@ -914,7 +914,7 @@ async function runDeterministicReplay(finding, opts = {}) {
|
|
|
914
914
|
const runner = opts.runner ?? new LocalShellRunner();
|
|
915
915
|
const stepTimeoutMs = opts.stepTimeoutMs ?? DEFAULT_STEP_TIMEOUT_MS;
|
|
916
916
|
const engineVersion = opts.engineVersion ?? VERSION;
|
|
917
|
-
const runDir = opts.runDir ?? mkdtempSync(join(tmpdir(), "
|
|
917
|
+
const runDir = opts.runDir ?? mkdtempSync(join(tmpdir(), "0-replay-"));
|
|
918
918
|
mkdirSync(runDir, { recursive: true });
|
|
919
919
|
const startedAt = /* @__PURE__ */ new Date();
|
|
920
920
|
const startMs = Date.now();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createRequire as
|
|
3
|
-
const require =
|
|
2
|
+
import { createRequire as __0CreateRequire } from "node:module";
|
|
3
|
+
const require = __0CreateRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
homeStateDir
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PC6RCKQV.js";
|
|
7
7
|
|
|
8
8
|
// packages/core/dist/cve/artifact-scraper.js
|
|
9
9
|
import { createHash } from "node:crypto";
|
|
@@ -275,7 +275,7 @@ async function fetchGhsa(cveId, plumbing, githubToken, log) {
|
|
|
275
275
|
const url = `https://api.github.com/advisories?cve_id=${encodeURIComponent(cveId)}`;
|
|
276
276
|
const headers = {
|
|
277
277
|
accept: "application/vnd.github+json",
|
|
278
|
-
"user-agent": "
|
|
278
|
+
"user-agent": "0-cve-scraper"
|
|
279
279
|
};
|
|
280
280
|
if (githubToken)
|
|
281
281
|
headers.authorization = `Bearer ${githubToken}`;
|
|
@@ -533,7 +533,7 @@ function clamp01(n) {
|
|
|
533
533
|
async function fetchGithubPocSearch(cveId, plumbing, githubToken, log) {
|
|
534
534
|
const headers = {
|
|
535
535
|
accept: "application/vnd.github+json",
|
|
536
|
-
"user-agent": "
|
|
536
|
+
"user-agent": "0-cve-scraper"
|
|
537
537
|
};
|
|
538
538
|
if (githubToken)
|
|
539
539
|
headers.authorization = `Bearer ${githubToken}`;
|