@node9/proxy 1.12.10 → 1.13.0
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/dist/cli.js +127 -8
- package/dist/cli.mjs +127 -8
- package/dist/index.js +6 -3
- package/dist/index.mjs +6 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1266,7 +1266,8 @@ var init_dlp = __esm({
|
|
|
1266
1266
|
name: "GitHub Token",
|
|
1267
1267
|
regex: /\bgh[pous]_[A-Za-z0-9]{36}\b/,
|
|
1268
1268
|
severity: "block",
|
|
1269
|
-
keywords: ["ghp_", "gho_", "ghu_", "ghs_"]
|
|
1269
|
+
keywords: ["ghp_", "gho_", "ghu_", "ghs_"],
|
|
1270
|
+
minEntropy: 3
|
|
1270
1271
|
},
|
|
1271
1272
|
{
|
|
1272
1273
|
name: "GitHub Fine-Grained PAT",
|
|
@@ -1317,7 +1318,8 @@ var init_dlp = __esm({
|
|
|
1317
1318
|
name: "GCP API Key",
|
|
1318
1319
|
regex: /\bAIza[0-9A-Za-z_-]{35}\b/,
|
|
1319
1320
|
severity: "block",
|
|
1320
|
-
keywords: ["aiza"]
|
|
1321
|
+
keywords: ["aiza"],
|
|
1322
|
+
minEntropy: 3
|
|
1321
1323
|
},
|
|
1322
1324
|
{
|
|
1323
1325
|
name: "GCP Service Account",
|
|
@@ -1564,7 +1566,8 @@ var init_dlp = __esm({
|
|
|
1564
1566
|
name: "Mapbox Access Token",
|
|
1565
1567
|
regex: /\bpk\.eyJ1[a-zA-Z0-9._-]{20,}\b/,
|
|
1566
1568
|
severity: "block",
|
|
1567
|
-
keywords: ["pk.eyj1"]
|
|
1569
|
+
keywords: ["pk.eyj1"],
|
|
1570
|
+
minEntropy: 3
|
|
1568
1571
|
},
|
|
1569
1572
|
// ── Notion ────────────────────────────────────────────────────────────────
|
|
1570
1573
|
{
|
|
@@ -9929,6 +9932,7 @@ function scanClaudeHistory(startDate, onProgress, onLine) {
|
|
|
9929
9932
|
continue;
|
|
9930
9933
|
}
|
|
9931
9934
|
const sessionCalls = [];
|
|
9935
|
+
const toolUseFilePaths = /* @__PURE__ */ new Map();
|
|
9932
9936
|
for (const line of raw.split("\n")) {
|
|
9933
9937
|
if (!line.trim()) continue;
|
|
9934
9938
|
onLine?.();
|
|
@@ -9971,6 +9975,33 @@ function scanClaudeHistory(startDate, onProgress, onLine) {
|
|
|
9971
9975
|
}
|
|
9972
9976
|
}
|
|
9973
9977
|
}
|
|
9978
|
+
for (const block of content2) {
|
|
9979
|
+
if (block.type !== "tool_result") continue;
|
|
9980
|
+
const filePath = block.tool_use_id ? toolUseFilePaths.get(block.tool_use_id) : void 0;
|
|
9981
|
+
if (filePath) {
|
|
9982
|
+
const ext = import_path17.default.extname(filePath).toLowerCase();
|
|
9983
|
+
if (CODE_EXTENSIONS.has(ext)) continue;
|
|
9984
|
+
}
|
|
9985
|
+
const resultText = typeof block.content === "string" ? block.content : Array.isArray(block.content) ? block.content.map((c) => c.text ?? "").join("\n") : null;
|
|
9986
|
+
if (!resultText) continue;
|
|
9987
|
+
const dlpMatch = scanArgs({ text: resultText });
|
|
9988
|
+
if (dlpMatch) {
|
|
9989
|
+
const isDupe = result.dlpFindings.some(
|
|
9990
|
+
(f) => f.patternName === dlpMatch.patternName && f.redactedSample === dlpMatch.redactedSample && f.project === projLabel
|
|
9991
|
+
);
|
|
9992
|
+
if (!isDupe) {
|
|
9993
|
+
result.dlpFindings.push({
|
|
9994
|
+
patternName: dlpMatch.patternName,
|
|
9995
|
+
redactedSample: dlpMatch.redactedSample,
|
|
9996
|
+
toolName: "tool-result",
|
|
9997
|
+
timestamp: entry.timestamp ?? "",
|
|
9998
|
+
project: projLabel,
|
|
9999
|
+
sessionId,
|
|
10000
|
+
agent: "claude"
|
|
10001
|
+
});
|
|
10002
|
+
}
|
|
10003
|
+
}
|
|
10004
|
+
}
|
|
9974
10005
|
}
|
|
9975
10006
|
continue;
|
|
9976
10007
|
}
|
|
@@ -9990,6 +10021,9 @@ function scanClaudeHistory(startDate, onProgress, onLine) {
|
|
|
9990
10021
|
const toolName = block.name ?? "";
|
|
9991
10022
|
const toolNameLower = toolName.toLowerCase();
|
|
9992
10023
|
const input = block.input ?? {};
|
|
10024
|
+
if (block.id && typeof input.file_path === "string") {
|
|
10025
|
+
toolUseFilePaths.set(block.id, input.file_path);
|
|
10026
|
+
}
|
|
9993
10027
|
sessionCalls.push({ toolName, input, timestamp: entry.timestamp ?? "" });
|
|
9994
10028
|
if (toolNameLower === "bash" || toolNameLower === "execute_bash") {
|
|
9995
10029
|
result.bashCalls++;
|
|
@@ -9997,6 +10031,9 @@ function scanClaudeHistory(startDate, onProgress, onLine) {
|
|
|
9997
10031
|
const rawCmd = String(input.command ?? "").trimStart();
|
|
9998
10032
|
if (/^node9\s+(scan|explain|report|tail|dlp|status|sessions|audit)\b/.test(rawCmd))
|
|
9999
10033
|
continue;
|
|
10034
|
+
const inputFilePath = typeof input.file_path === "string" ? input.file_path : "";
|
|
10035
|
+
const inputFileExt = inputFilePath ? import_path17.default.extname(inputFilePath).toLowerCase() : "";
|
|
10036
|
+
if (CODE_EXTENSIONS.has(inputFileExt)) continue;
|
|
10000
10037
|
const dlpMatch = scanArgs(input);
|
|
10001
10038
|
if (dlpMatch) {
|
|
10002
10039
|
const isDupe = result.dlpFindings.some(
|
|
@@ -10493,6 +10530,44 @@ function scanCodexHistory(startDate, onProgress, onLine) {
|
|
|
10493
10530
|
}
|
|
10494
10531
|
return result;
|
|
10495
10532
|
}
|
|
10533
|
+
function scanShellConfig() {
|
|
10534
|
+
const home = import_os12.default.homedir();
|
|
10535
|
+
const configFiles = [".zshrc", ".bashrc", ".bash_profile", ".profile"].map(
|
|
10536
|
+
(f) => import_path17.default.join(home, f)
|
|
10537
|
+
);
|
|
10538
|
+
const findings = [];
|
|
10539
|
+
for (const filePath of configFiles) {
|
|
10540
|
+
if (!import_fs14.default.existsSync(filePath)) continue;
|
|
10541
|
+
let lines;
|
|
10542
|
+
try {
|
|
10543
|
+
lines = import_fs14.default.readFileSync(filePath, "utf-8").split("\n");
|
|
10544
|
+
} catch {
|
|
10545
|
+
continue;
|
|
10546
|
+
}
|
|
10547
|
+
const shortPath = filePath.replace(home, "~");
|
|
10548
|
+
for (const line of lines) {
|
|
10549
|
+
const trimmed = line.trim();
|
|
10550
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
10551
|
+
const dlpMatch = scanArgs({ text: trimmed });
|
|
10552
|
+
if (!dlpMatch) continue;
|
|
10553
|
+
const isDupe = findings.some(
|
|
10554
|
+
(f) => f.patternName === dlpMatch.patternName && f.redactedSample === dlpMatch.redactedSample && f.project === shortPath
|
|
10555
|
+
);
|
|
10556
|
+
if (!isDupe) {
|
|
10557
|
+
findings.push({
|
|
10558
|
+
patternName: dlpMatch.patternName,
|
|
10559
|
+
redactedSample: dlpMatch.redactedSample,
|
|
10560
|
+
toolName: "shell-config",
|
|
10561
|
+
timestamp: "",
|
|
10562
|
+
project: shortPath,
|
|
10563
|
+
sessionId: "",
|
|
10564
|
+
agent: "shell"
|
|
10565
|
+
});
|
|
10566
|
+
}
|
|
10567
|
+
}
|
|
10568
|
+
}
|
|
10569
|
+
return findings;
|
|
10570
|
+
}
|
|
10496
10571
|
function mergeScans(a, b) {
|
|
10497
10572
|
const dates = [a.firstDate, b.firstDate].filter(Boolean);
|
|
10498
10573
|
const lastDates = [a.lastDate, b.lastDate].filter(Boolean);
|
|
@@ -10607,6 +10682,7 @@ function registerScanCommand(program2) {
|
|
|
10607
10682
|
onLine
|
|
10608
10683
|
);
|
|
10609
10684
|
const scan = mergeScans(mergeScans(claudeScan, geminiScan), codexScan);
|
|
10685
|
+
scan.dlpFindings.push(...scanShellConfig());
|
|
10610
10686
|
const summary = buildScanSummary([
|
|
10611
10687
|
{ id: "claude", label: "Claude", icon: "\u{1F916}", scan: claudeScan },
|
|
10612
10688
|
{ id: "gemini", label: "Gemini", icon: "\u264A", scan: geminiScan },
|
|
@@ -10660,7 +10736,7 @@ function registerScanCommand(program2) {
|
|
|
10660
10736
|
}
|
|
10661
10737
|
if (scan.dlpFindings.length > 0) {
|
|
10662
10738
|
console.log(
|
|
10663
|
-
" " + import_chalk2.default.red("\u{1F511} Credential leak") + " " + import_chalk2.default.red.bold(String(scan.dlpFindings.length).padStart(5)) + import_chalk2.default.dim(" secret detected in
|
|
10739
|
+
" " + import_chalk2.default.red("\u{1F511} Credential leak") + " " + import_chalk2.default.red.bold(String(scan.dlpFindings.length).padStart(5)) + import_chalk2.default.dim(" secret detected in history or shell config")
|
|
10664
10740
|
);
|
|
10665
10741
|
}
|
|
10666
10742
|
if (blockedCount > 0) {
|
|
@@ -10669,8 +10745,9 @@ function registerScanCommand(program2) {
|
|
|
10669
10745
|
);
|
|
10670
10746
|
}
|
|
10671
10747
|
if (scan.loopFindings.length > 0) {
|
|
10748
|
+
const loopCost = summary.loopWastedUSD > 0 ? import_chalk2.default.dim(" \xB7 ") + import_chalk2.default.yellow("~" + fmtCost(summary.loopWastedUSD) + " wasted") : "";
|
|
10672
10749
|
console.log(
|
|
10673
|
-
" " + import_chalk2.default.yellow("\u{1F501} Loop detected") + " " + import_chalk2.default.yellow.bold(String(scan.loopFindings.length).padStart(5)) + import_chalk2.default.dim(" repeated tool call patterns found")
|
|
10750
|
+
" " + import_chalk2.default.yellow("\u{1F501} Loop detected") + " " + import_chalk2.default.yellow.bold(String(scan.loopFindings.length).padStart(5)) + import_chalk2.default.dim(" repeated tool call patterns found") + loopCost
|
|
10674
10751
|
);
|
|
10675
10752
|
}
|
|
10676
10753
|
if (reviewCount > 0) {
|
|
@@ -10690,7 +10767,7 @@ function registerScanCommand(program2) {
|
|
|
10690
10767
|
for (const f of shownDlp) {
|
|
10691
10768
|
const ts = f.timestamp ? import_chalk2.default.dim(fmtTs(f.timestamp) + " ") : "";
|
|
10692
10769
|
const proj = import_chalk2.default.dim(f.project.slice(0, 22).padEnd(22) + " ");
|
|
10693
|
-
const agentBadge = f.agent === "gemini" ? import_chalk2.default.blue("[Gemini] ") : f.agent === "codex" ? import_chalk2.default.magenta("[Codex] ") : import_chalk2.default.cyan("[Claude] ");
|
|
10770
|
+
const agentBadge = f.agent === "gemini" ? import_chalk2.default.blue("[Gemini] ") : f.agent === "codex" ? import_chalk2.default.magenta("[Codex] ") : f.agent === "shell" ? import_chalk2.default.yellow("[Shell] ") : import_chalk2.default.cyan("[Claude] ");
|
|
10694
10771
|
const sessionSuffix = f.sessionId ? import_chalk2.default.dim(` \u2192 ${f.sessionId.slice(0, 8)}`) : "";
|
|
10695
10772
|
console.log(
|
|
10696
10773
|
` \u{1F6A8} ${ts}${proj}${agentBadge}` + import_chalk2.default.yellow(f.patternName) + import_chalk2.default.dim(" ") + import_chalk2.default.gray(f.redactedSample) + sessionSuffix
|
|
@@ -10722,10 +10799,11 @@ function registerScanCommand(program2) {
|
|
|
10722
10799
|
}
|
|
10723
10800
|
if (scan.loopFindings.length > 0) {
|
|
10724
10801
|
console.log(" " + import_chalk2.default.dim("\u2500".repeat(70)));
|
|
10802
|
+
const loopCostLabel = summary.loopWastedUSD > 0 ? import_chalk2.default.dim(" \xB7 ") + import_chalk2.default.yellow("~" + fmtCost(summary.loopWastedUSD) + " wasted") : "";
|
|
10725
10803
|
console.log(
|
|
10726
10804
|
" " + import_chalk2.default.yellow.bold("\u{1F501} Agent Loops") + import_chalk2.default.dim(" \xB7 ") + import_chalk2.default.yellow(
|
|
10727
10805
|
`${num(scan.loopFindings.length)} repeated pattern${scan.loopFindings.length !== 1 ? "s" : ""} found`
|
|
10728
|
-
)
|
|
10806
|
+
) + loopCostLabel
|
|
10729
10807
|
);
|
|
10730
10808
|
const shownLoops = drillDown ? scan.loopFindings : scan.loopFindings.slice(0, topN);
|
|
10731
10809
|
for (const f of shownLoops) {
|
|
@@ -10848,7 +10926,7 @@ function registerScanCommand(program2) {
|
|
|
10848
10926
|
}
|
|
10849
10927
|
});
|
|
10850
10928
|
}
|
|
10851
|
-
var import_chalk2, import_fs14, import_path17, import_os12, CLAUDE_PRICING, GEMINI_PRICING, LOOP_TOOLS, LOOP_THRESHOLD, DEFAULT_RULE_NAMES;
|
|
10929
|
+
var import_chalk2, import_fs14, import_path17, import_os12, CLAUDE_PRICING, GEMINI_PRICING, CODE_EXTENSIONS, LOOP_TOOLS, LOOP_THRESHOLD, DEFAULT_RULE_NAMES;
|
|
10852
10930
|
var init_scan = __esm({
|
|
10853
10931
|
"src/cli/commands/scan.ts"() {
|
|
10854
10932
|
"use strict";
|
|
@@ -10884,6 +10962,33 @@ var init_scan = __esm({
|
|
|
10884
10962
|
"gemini-1.5-flash": { i: 75e-9, o: 3e-7, cr: 1875e-11 },
|
|
10885
10963
|
"gemini-3-flash": { i: 1e-7, o: 4e-7, cr: 25e-9 }
|
|
10886
10964
|
};
|
|
10965
|
+
CODE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
10966
|
+
".ts",
|
|
10967
|
+
".tsx",
|
|
10968
|
+
".js",
|
|
10969
|
+
".jsx",
|
|
10970
|
+
".mjs",
|
|
10971
|
+
".cjs",
|
|
10972
|
+
".py",
|
|
10973
|
+
".rb",
|
|
10974
|
+
".go",
|
|
10975
|
+
".rs",
|
|
10976
|
+
".java",
|
|
10977
|
+
".kt",
|
|
10978
|
+
".swift",
|
|
10979
|
+
".c",
|
|
10980
|
+
".cpp",
|
|
10981
|
+
".h",
|
|
10982
|
+
".cs",
|
|
10983
|
+
".php",
|
|
10984
|
+
".sh",
|
|
10985
|
+
".bash",
|
|
10986
|
+
".html",
|
|
10987
|
+
".css",
|
|
10988
|
+
".scss",
|
|
10989
|
+
".vue",
|
|
10990
|
+
".svelte"
|
|
10991
|
+
]);
|
|
10887
10992
|
LOOP_TOOLS = /* @__PURE__ */ new Set([
|
|
10888
10993
|
"bash",
|
|
10889
10994
|
"execute_bash",
|
|
@@ -17566,6 +17671,7 @@ init_core();
|
|
|
17566
17671
|
init_setup();
|
|
17567
17672
|
init_shields();
|
|
17568
17673
|
init_service();
|
|
17674
|
+
init_daemon_starter();
|
|
17569
17675
|
var DEFAULT_SHIELDS = ["bash-safe", "filesystem", "postgres"];
|
|
17570
17676
|
function fireTelemetryPing(agents) {
|
|
17571
17677
|
try {
|
|
@@ -17704,6 +17810,19 @@ function registerInitCommand(program2) {
|
|
|
17704
17810
|
} else {
|
|
17705
17811
|
console.log(import_chalk13.default.green(" \u2713 Daemon login service already installed"));
|
|
17706
17812
|
}
|
|
17813
|
+
if (!isTestingMode()) {
|
|
17814
|
+
process.stdout.write(import_chalk13.default.dim(" Starting daemon..."));
|
|
17815
|
+
const started = await autoStartDaemonAndWait(false);
|
|
17816
|
+
if (started) {
|
|
17817
|
+
process.stdout.write(
|
|
17818
|
+
"\r" + import_chalk13.default.green(" \u2713 Daemon started \u2014 protection is active") + "\n"
|
|
17819
|
+
);
|
|
17820
|
+
} else {
|
|
17821
|
+
process.stdout.write(
|
|
17822
|
+
"\r" + import_chalk13.default.dim(" Daemon will start on next login ") + "\n"
|
|
17823
|
+
);
|
|
17824
|
+
}
|
|
17825
|
+
}
|
|
17707
17826
|
console.log("");
|
|
17708
17827
|
}
|
|
17709
17828
|
{
|
package/dist/cli.mjs
CHANGED
|
@@ -1244,7 +1244,8 @@ var init_dlp = __esm({
|
|
|
1244
1244
|
name: "GitHub Token",
|
|
1245
1245
|
regex: /\bgh[pous]_[A-Za-z0-9]{36}\b/,
|
|
1246
1246
|
severity: "block",
|
|
1247
|
-
keywords: ["ghp_", "gho_", "ghu_", "ghs_"]
|
|
1247
|
+
keywords: ["ghp_", "gho_", "ghu_", "ghs_"],
|
|
1248
|
+
minEntropy: 3
|
|
1248
1249
|
},
|
|
1249
1250
|
{
|
|
1250
1251
|
name: "GitHub Fine-Grained PAT",
|
|
@@ -1295,7 +1296,8 @@ var init_dlp = __esm({
|
|
|
1295
1296
|
name: "GCP API Key",
|
|
1296
1297
|
regex: /\bAIza[0-9A-Za-z_-]{35}\b/,
|
|
1297
1298
|
severity: "block",
|
|
1298
|
-
keywords: ["aiza"]
|
|
1299
|
+
keywords: ["aiza"],
|
|
1300
|
+
minEntropy: 3
|
|
1299
1301
|
},
|
|
1300
1302
|
{
|
|
1301
1303
|
name: "GCP Service Account",
|
|
@@ -1542,7 +1544,8 @@ var init_dlp = __esm({
|
|
|
1542
1544
|
name: "Mapbox Access Token",
|
|
1543
1545
|
regex: /\bpk\.eyJ1[a-zA-Z0-9._-]{20,}\b/,
|
|
1544
1546
|
severity: "block",
|
|
1545
|
-
keywords: ["pk.eyj1"]
|
|
1547
|
+
keywords: ["pk.eyj1"],
|
|
1548
|
+
minEntropy: 3
|
|
1546
1549
|
},
|
|
1547
1550
|
// ── Notion ────────────────────────────────────────────────────────────────
|
|
1548
1551
|
{
|
|
@@ -9909,6 +9912,7 @@ function scanClaudeHistory(startDate, onProgress, onLine) {
|
|
|
9909
9912
|
continue;
|
|
9910
9913
|
}
|
|
9911
9914
|
const sessionCalls = [];
|
|
9915
|
+
const toolUseFilePaths = /* @__PURE__ */ new Map();
|
|
9912
9916
|
for (const line of raw.split("\n")) {
|
|
9913
9917
|
if (!line.trim()) continue;
|
|
9914
9918
|
onLine?.();
|
|
@@ -9951,6 +9955,33 @@ function scanClaudeHistory(startDate, onProgress, onLine) {
|
|
|
9951
9955
|
}
|
|
9952
9956
|
}
|
|
9953
9957
|
}
|
|
9958
|
+
for (const block of content2) {
|
|
9959
|
+
if (block.type !== "tool_result") continue;
|
|
9960
|
+
const filePath = block.tool_use_id ? toolUseFilePaths.get(block.tool_use_id) : void 0;
|
|
9961
|
+
if (filePath) {
|
|
9962
|
+
const ext = path17.extname(filePath).toLowerCase();
|
|
9963
|
+
if (CODE_EXTENSIONS.has(ext)) continue;
|
|
9964
|
+
}
|
|
9965
|
+
const resultText = typeof block.content === "string" ? block.content : Array.isArray(block.content) ? block.content.map((c) => c.text ?? "").join("\n") : null;
|
|
9966
|
+
if (!resultText) continue;
|
|
9967
|
+
const dlpMatch = scanArgs({ text: resultText });
|
|
9968
|
+
if (dlpMatch) {
|
|
9969
|
+
const isDupe = result.dlpFindings.some(
|
|
9970
|
+
(f) => f.patternName === dlpMatch.patternName && f.redactedSample === dlpMatch.redactedSample && f.project === projLabel
|
|
9971
|
+
);
|
|
9972
|
+
if (!isDupe) {
|
|
9973
|
+
result.dlpFindings.push({
|
|
9974
|
+
patternName: dlpMatch.patternName,
|
|
9975
|
+
redactedSample: dlpMatch.redactedSample,
|
|
9976
|
+
toolName: "tool-result",
|
|
9977
|
+
timestamp: entry.timestamp ?? "",
|
|
9978
|
+
project: projLabel,
|
|
9979
|
+
sessionId,
|
|
9980
|
+
agent: "claude"
|
|
9981
|
+
});
|
|
9982
|
+
}
|
|
9983
|
+
}
|
|
9984
|
+
}
|
|
9954
9985
|
}
|
|
9955
9986
|
continue;
|
|
9956
9987
|
}
|
|
@@ -9970,6 +10001,9 @@ function scanClaudeHistory(startDate, onProgress, onLine) {
|
|
|
9970
10001
|
const toolName = block.name ?? "";
|
|
9971
10002
|
const toolNameLower = toolName.toLowerCase();
|
|
9972
10003
|
const input = block.input ?? {};
|
|
10004
|
+
if (block.id && typeof input.file_path === "string") {
|
|
10005
|
+
toolUseFilePaths.set(block.id, input.file_path);
|
|
10006
|
+
}
|
|
9973
10007
|
sessionCalls.push({ toolName, input, timestamp: entry.timestamp ?? "" });
|
|
9974
10008
|
if (toolNameLower === "bash" || toolNameLower === "execute_bash") {
|
|
9975
10009
|
result.bashCalls++;
|
|
@@ -9977,6 +10011,9 @@ function scanClaudeHistory(startDate, onProgress, onLine) {
|
|
|
9977
10011
|
const rawCmd = String(input.command ?? "").trimStart();
|
|
9978
10012
|
if (/^node9\s+(scan|explain|report|tail|dlp|status|sessions|audit)\b/.test(rawCmd))
|
|
9979
10013
|
continue;
|
|
10014
|
+
const inputFilePath = typeof input.file_path === "string" ? input.file_path : "";
|
|
10015
|
+
const inputFileExt = inputFilePath ? path17.extname(inputFilePath).toLowerCase() : "";
|
|
10016
|
+
if (CODE_EXTENSIONS.has(inputFileExt)) continue;
|
|
9980
10017
|
const dlpMatch = scanArgs(input);
|
|
9981
10018
|
if (dlpMatch) {
|
|
9982
10019
|
const isDupe = result.dlpFindings.some(
|
|
@@ -10473,6 +10510,44 @@ function scanCodexHistory(startDate, onProgress, onLine) {
|
|
|
10473
10510
|
}
|
|
10474
10511
|
return result;
|
|
10475
10512
|
}
|
|
10513
|
+
function scanShellConfig() {
|
|
10514
|
+
const home = os12.homedir();
|
|
10515
|
+
const configFiles = [".zshrc", ".bashrc", ".bash_profile", ".profile"].map(
|
|
10516
|
+
(f) => path17.join(home, f)
|
|
10517
|
+
);
|
|
10518
|
+
const findings = [];
|
|
10519
|
+
for (const filePath of configFiles) {
|
|
10520
|
+
if (!fs14.existsSync(filePath)) continue;
|
|
10521
|
+
let lines;
|
|
10522
|
+
try {
|
|
10523
|
+
lines = fs14.readFileSync(filePath, "utf-8").split("\n");
|
|
10524
|
+
} catch {
|
|
10525
|
+
continue;
|
|
10526
|
+
}
|
|
10527
|
+
const shortPath = filePath.replace(home, "~");
|
|
10528
|
+
for (const line of lines) {
|
|
10529
|
+
const trimmed = line.trim();
|
|
10530
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
10531
|
+
const dlpMatch = scanArgs({ text: trimmed });
|
|
10532
|
+
if (!dlpMatch) continue;
|
|
10533
|
+
const isDupe = findings.some(
|
|
10534
|
+
(f) => f.patternName === dlpMatch.patternName && f.redactedSample === dlpMatch.redactedSample && f.project === shortPath
|
|
10535
|
+
);
|
|
10536
|
+
if (!isDupe) {
|
|
10537
|
+
findings.push({
|
|
10538
|
+
patternName: dlpMatch.patternName,
|
|
10539
|
+
redactedSample: dlpMatch.redactedSample,
|
|
10540
|
+
toolName: "shell-config",
|
|
10541
|
+
timestamp: "",
|
|
10542
|
+
project: shortPath,
|
|
10543
|
+
sessionId: "",
|
|
10544
|
+
agent: "shell"
|
|
10545
|
+
});
|
|
10546
|
+
}
|
|
10547
|
+
}
|
|
10548
|
+
}
|
|
10549
|
+
return findings;
|
|
10550
|
+
}
|
|
10476
10551
|
function mergeScans(a, b) {
|
|
10477
10552
|
const dates = [a.firstDate, b.firstDate].filter(Boolean);
|
|
10478
10553
|
const lastDates = [a.lastDate, b.lastDate].filter(Boolean);
|
|
@@ -10587,6 +10662,7 @@ function registerScanCommand(program2) {
|
|
|
10587
10662
|
onLine
|
|
10588
10663
|
);
|
|
10589
10664
|
const scan = mergeScans(mergeScans(claudeScan, geminiScan), codexScan);
|
|
10665
|
+
scan.dlpFindings.push(...scanShellConfig());
|
|
10590
10666
|
const summary = buildScanSummary([
|
|
10591
10667
|
{ id: "claude", label: "Claude", icon: "\u{1F916}", scan: claudeScan },
|
|
10592
10668
|
{ id: "gemini", label: "Gemini", icon: "\u264A", scan: geminiScan },
|
|
@@ -10640,7 +10716,7 @@ function registerScanCommand(program2) {
|
|
|
10640
10716
|
}
|
|
10641
10717
|
if (scan.dlpFindings.length > 0) {
|
|
10642
10718
|
console.log(
|
|
10643
|
-
" " + chalk2.red("\u{1F511} Credential leak") + " " + chalk2.red.bold(String(scan.dlpFindings.length).padStart(5)) + chalk2.dim(" secret detected in
|
|
10719
|
+
" " + chalk2.red("\u{1F511} Credential leak") + " " + chalk2.red.bold(String(scan.dlpFindings.length).padStart(5)) + chalk2.dim(" secret detected in history or shell config")
|
|
10644
10720
|
);
|
|
10645
10721
|
}
|
|
10646
10722
|
if (blockedCount > 0) {
|
|
@@ -10649,8 +10725,9 @@ function registerScanCommand(program2) {
|
|
|
10649
10725
|
);
|
|
10650
10726
|
}
|
|
10651
10727
|
if (scan.loopFindings.length > 0) {
|
|
10728
|
+
const loopCost = summary.loopWastedUSD > 0 ? chalk2.dim(" \xB7 ") + chalk2.yellow("~" + fmtCost(summary.loopWastedUSD) + " wasted") : "";
|
|
10652
10729
|
console.log(
|
|
10653
|
-
" " + chalk2.yellow("\u{1F501} Loop detected") + " " + chalk2.yellow.bold(String(scan.loopFindings.length).padStart(5)) + chalk2.dim(" repeated tool call patterns found")
|
|
10730
|
+
" " + chalk2.yellow("\u{1F501} Loop detected") + " " + chalk2.yellow.bold(String(scan.loopFindings.length).padStart(5)) + chalk2.dim(" repeated tool call patterns found") + loopCost
|
|
10654
10731
|
);
|
|
10655
10732
|
}
|
|
10656
10733
|
if (reviewCount > 0) {
|
|
@@ -10670,7 +10747,7 @@ function registerScanCommand(program2) {
|
|
|
10670
10747
|
for (const f of shownDlp) {
|
|
10671
10748
|
const ts = f.timestamp ? chalk2.dim(fmtTs(f.timestamp) + " ") : "";
|
|
10672
10749
|
const proj = chalk2.dim(f.project.slice(0, 22).padEnd(22) + " ");
|
|
10673
|
-
const agentBadge = f.agent === "gemini" ? chalk2.blue("[Gemini] ") : f.agent === "codex" ? chalk2.magenta("[Codex] ") : chalk2.cyan("[Claude] ");
|
|
10750
|
+
const agentBadge = f.agent === "gemini" ? chalk2.blue("[Gemini] ") : f.agent === "codex" ? chalk2.magenta("[Codex] ") : f.agent === "shell" ? chalk2.yellow("[Shell] ") : chalk2.cyan("[Claude] ");
|
|
10674
10751
|
const sessionSuffix = f.sessionId ? chalk2.dim(` \u2192 ${f.sessionId.slice(0, 8)}`) : "";
|
|
10675
10752
|
console.log(
|
|
10676
10753
|
` \u{1F6A8} ${ts}${proj}${agentBadge}` + chalk2.yellow(f.patternName) + chalk2.dim(" ") + chalk2.gray(f.redactedSample) + sessionSuffix
|
|
@@ -10702,10 +10779,11 @@ function registerScanCommand(program2) {
|
|
|
10702
10779
|
}
|
|
10703
10780
|
if (scan.loopFindings.length > 0) {
|
|
10704
10781
|
console.log(" " + chalk2.dim("\u2500".repeat(70)));
|
|
10782
|
+
const loopCostLabel = summary.loopWastedUSD > 0 ? chalk2.dim(" \xB7 ") + chalk2.yellow("~" + fmtCost(summary.loopWastedUSD) + " wasted") : "";
|
|
10705
10783
|
console.log(
|
|
10706
10784
|
" " + chalk2.yellow.bold("\u{1F501} Agent Loops") + chalk2.dim(" \xB7 ") + chalk2.yellow(
|
|
10707
10785
|
`${num(scan.loopFindings.length)} repeated pattern${scan.loopFindings.length !== 1 ? "s" : ""} found`
|
|
10708
|
-
)
|
|
10786
|
+
) + loopCostLabel
|
|
10709
10787
|
);
|
|
10710
10788
|
const shownLoops = drillDown ? scan.loopFindings : scan.loopFindings.slice(0, topN);
|
|
10711
10789
|
for (const f of shownLoops) {
|
|
@@ -10828,7 +10906,7 @@ function registerScanCommand(program2) {
|
|
|
10828
10906
|
}
|
|
10829
10907
|
});
|
|
10830
10908
|
}
|
|
10831
|
-
var CLAUDE_PRICING, GEMINI_PRICING, LOOP_TOOLS, LOOP_THRESHOLD, DEFAULT_RULE_NAMES;
|
|
10909
|
+
var CLAUDE_PRICING, GEMINI_PRICING, CODE_EXTENSIONS, LOOP_TOOLS, LOOP_THRESHOLD, DEFAULT_RULE_NAMES;
|
|
10832
10910
|
var init_scan = __esm({
|
|
10833
10911
|
"src/cli/commands/scan.ts"() {
|
|
10834
10912
|
"use strict";
|
|
@@ -10860,6 +10938,33 @@ var init_scan = __esm({
|
|
|
10860
10938
|
"gemini-1.5-flash": { i: 75e-9, o: 3e-7, cr: 1875e-11 },
|
|
10861
10939
|
"gemini-3-flash": { i: 1e-7, o: 4e-7, cr: 25e-9 }
|
|
10862
10940
|
};
|
|
10941
|
+
CODE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
10942
|
+
".ts",
|
|
10943
|
+
".tsx",
|
|
10944
|
+
".js",
|
|
10945
|
+
".jsx",
|
|
10946
|
+
".mjs",
|
|
10947
|
+
".cjs",
|
|
10948
|
+
".py",
|
|
10949
|
+
".rb",
|
|
10950
|
+
".go",
|
|
10951
|
+
".rs",
|
|
10952
|
+
".java",
|
|
10953
|
+
".kt",
|
|
10954
|
+
".swift",
|
|
10955
|
+
".c",
|
|
10956
|
+
".cpp",
|
|
10957
|
+
".h",
|
|
10958
|
+
".cs",
|
|
10959
|
+
".php",
|
|
10960
|
+
".sh",
|
|
10961
|
+
".bash",
|
|
10962
|
+
".html",
|
|
10963
|
+
".css",
|
|
10964
|
+
".scss",
|
|
10965
|
+
".vue",
|
|
10966
|
+
".svelte"
|
|
10967
|
+
]);
|
|
10863
10968
|
LOOP_TOOLS = /* @__PURE__ */ new Set([
|
|
10864
10969
|
"bash",
|
|
10865
10970
|
"execute_bash",
|
|
@@ -17535,6 +17640,7 @@ init_core();
|
|
|
17535
17640
|
init_setup();
|
|
17536
17641
|
init_shields();
|
|
17537
17642
|
init_service();
|
|
17643
|
+
init_daemon_starter();
|
|
17538
17644
|
import chalk13 from "chalk";
|
|
17539
17645
|
import fs33 from "fs";
|
|
17540
17646
|
import path35 from "path";
|
|
@@ -17678,6 +17784,19 @@ function registerInitCommand(program2) {
|
|
|
17678
17784
|
} else {
|
|
17679
17785
|
console.log(chalk13.green(" \u2713 Daemon login service already installed"));
|
|
17680
17786
|
}
|
|
17787
|
+
if (!isTestingMode()) {
|
|
17788
|
+
process.stdout.write(chalk13.dim(" Starting daemon..."));
|
|
17789
|
+
const started = await autoStartDaemonAndWait(false);
|
|
17790
|
+
if (started) {
|
|
17791
|
+
process.stdout.write(
|
|
17792
|
+
"\r" + chalk13.green(" \u2713 Daemon started \u2014 protection is active") + "\n"
|
|
17793
|
+
);
|
|
17794
|
+
} else {
|
|
17795
|
+
process.stdout.write(
|
|
17796
|
+
"\r" + chalk13.dim(" Daemon will start on next login ") + "\n"
|
|
17797
|
+
);
|
|
17798
|
+
}
|
|
17799
|
+
}
|
|
17681
17800
|
console.log("");
|
|
17682
17801
|
}
|
|
17683
17802
|
{
|
package/dist/index.js
CHANGED
|
@@ -1045,7 +1045,8 @@ var DLP_PATTERNS = [
|
|
|
1045
1045
|
name: "GitHub Token",
|
|
1046
1046
|
regex: /\bgh[pous]_[A-Za-z0-9]{36}\b/,
|
|
1047
1047
|
severity: "block",
|
|
1048
|
-
keywords: ["ghp_", "gho_", "ghu_", "ghs_"]
|
|
1048
|
+
keywords: ["ghp_", "gho_", "ghu_", "ghs_"],
|
|
1049
|
+
minEntropy: 3
|
|
1049
1050
|
},
|
|
1050
1051
|
{
|
|
1051
1052
|
name: "GitHub Fine-Grained PAT",
|
|
@@ -1096,7 +1097,8 @@ var DLP_PATTERNS = [
|
|
|
1096
1097
|
name: "GCP API Key",
|
|
1097
1098
|
regex: /\bAIza[0-9A-Za-z_-]{35}\b/,
|
|
1098
1099
|
severity: "block",
|
|
1099
|
-
keywords: ["aiza"]
|
|
1100
|
+
keywords: ["aiza"],
|
|
1101
|
+
minEntropy: 3
|
|
1100
1102
|
},
|
|
1101
1103
|
{
|
|
1102
1104
|
name: "GCP Service Account",
|
|
@@ -1343,7 +1345,8 @@ var DLP_PATTERNS = [
|
|
|
1343
1345
|
name: "Mapbox Access Token",
|
|
1344
1346
|
regex: /\bpk\.eyJ1[a-zA-Z0-9._-]{20,}\b/,
|
|
1345
1347
|
severity: "block",
|
|
1346
|
-
keywords: ["pk.eyj1"]
|
|
1348
|
+
keywords: ["pk.eyj1"],
|
|
1349
|
+
minEntropy: 3
|
|
1347
1350
|
},
|
|
1348
1351
|
// ── Notion ────────────────────────────────────────────────────────────────
|
|
1349
1352
|
{
|
package/dist/index.mjs
CHANGED
|
@@ -1015,7 +1015,8 @@ var DLP_PATTERNS = [
|
|
|
1015
1015
|
name: "GitHub Token",
|
|
1016
1016
|
regex: /\bgh[pous]_[A-Za-z0-9]{36}\b/,
|
|
1017
1017
|
severity: "block",
|
|
1018
|
-
keywords: ["ghp_", "gho_", "ghu_", "ghs_"]
|
|
1018
|
+
keywords: ["ghp_", "gho_", "ghu_", "ghs_"],
|
|
1019
|
+
minEntropy: 3
|
|
1019
1020
|
},
|
|
1020
1021
|
{
|
|
1021
1022
|
name: "GitHub Fine-Grained PAT",
|
|
@@ -1066,7 +1067,8 @@ var DLP_PATTERNS = [
|
|
|
1066
1067
|
name: "GCP API Key",
|
|
1067
1068
|
regex: /\bAIza[0-9A-Za-z_-]{35}\b/,
|
|
1068
1069
|
severity: "block",
|
|
1069
|
-
keywords: ["aiza"]
|
|
1070
|
+
keywords: ["aiza"],
|
|
1071
|
+
minEntropy: 3
|
|
1070
1072
|
},
|
|
1071
1073
|
{
|
|
1072
1074
|
name: "GCP Service Account",
|
|
@@ -1313,7 +1315,8 @@ var DLP_PATTERNS = [
|
|
|
1313
1315
|
name: "Mapbox Access Token",
|
|
1314
1316
|
regex: /\bpk\.eyJ1[a-zA-Z0-9._-]{20,}\b/,
|
|
1315
1317
|
severity: "block",
|
|
1316
|
-
keywords: ["pk.eyj1"]
|
|
1318
|
+
keywords: ["pk.eyj1"],
|
|
1319
|
+
minEntropy: 3
|
|
1317
1320
|
},
|
|
1318
1321
|
// ── Notion ────────────────────────────────────────────────────────────────
|
|
1319
1322
|
{
|