pwnkit-cli 0.1.5 → 0.1.6
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/index.js +58 -102
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10402,10 +10402,11 @@ __export(process_exports, {
|
|
|
10402
10402
|
ProcessRuntime: () => ProcessRuntime
|
|
10403
10403
|
});
|
|
10404
10404
|
import { spawn } from "node:child_process";
|
|
10405
|
-
var RUNTIME_COMMANDS, ProcessRuntime;
|
|
10405
|
+
var dim, RUNTIME_COMMANDS, ProcessRuntime;
|
|
10406
10406
|
var init_process = __esm({
|
|
10407
10407
|
"packages/core/dist/runtime/process.js"() {
|
|
10408
10408
|
"use strict";
|
|
10409
|
+
dim = (text2) => `\x1B[2m${text2}\x1B[0m`;
|
|
10409
10410
|
RUNTIME_COMMANDS = {
|
|
10410
10411
|
claude: "claude",
|
|
10411
10412
|
codex: "codex",
|
|
@@ -10438,7 +10439,11 @@ var init_process = __esm({
|
|
|
10438
10439
|
stdout += chunk.toString();
|
|
10439
10440
|
});
|
|
10440
10441
|
proc.stderr.on("data", (chunk) => {
|
|
10441
|
-
|
|
10442
|
+
const text2 = chunk.toString();
|
|
10443
|
+
stderr += text2;
|
|
10444
|
+
if (process.stderr.isTTY) {
|
|
10445
|
+
process.stderr.write(dim(text2));
|
|
10446
|
+
}
|
|
10442
10447
|
});
|
|
10443
10448
|
const timer = setTimeout(() => {
|
|
10444
10449
|
timedOut = true;
|
|
@@ -11100,15 +11105,17 @@ async function runNativeAgentLoop(opts) {
|
|
|
11100
11105
|
state.totalUsage.inputTokens += result.usage.inputTokens;
|
|
11101
11106
|
state.totalUsage.outputTokens += result.usage.outputTokens;
|
|
11102
11107
|
}
|
|
11103
|
-
if (result.error) {
|
|
11104
|
-
|
|
11108
|
+
if (result.error || result.content.length === 0 && (!result.usage || result.usage.outputTokens === 0)) {
|
|
11109
|
+
const errorMsg = result.error || "API returned empty response (0 tokens) \u2014 model may be rate-limited or unavailable";
|
|
11110
|
+
onEvent?.("agent_error", { turn: state.turnCount, error: errorMsg });
|
|
11111
|
+
state.summary = `Error: ${errorMsg}`;
|
|
11105
11112
|
if (db) {
|
|
11106
11113
|
db.logEvent({
|
|
11107
11114
|
scanId: config.scanId,
|
|
11108
11115
|
stage: config.role,
|
|
11109
11116
|
eventType: "agent_error",
|
|
11110
11117
|
agentRole: config.role,
|
|
11111
|
-
payload: { turn: state.turnCount, error:
|
|
11118
|
+
payload: { turn: state.turnCount, error: errorMsg },
|
|
11112
11119
|
timestamp: Date.now()
|
|
11113
11120
|
});
|
|
11114
11121
|
}
|
|
@@ -14039,7 +14046,7 @@ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
|
14039
14046
|
var source_default = chalk;
|
|
14040
14047
|
|
|
14041
14048
|
// packages/shared/dist/constants.js
|
|
14042
|
-
var VERSION = "0.1.
|
|
14049
|
+
var VERSION = "0.1.6";
|
|
14043
14050
|
var DEPTH_CONFIG = {
|
|
14044
14051
|
quick: { maxTemplates: 5, maxPayloadsPerTemplate: 1, multiTurn: false },
|
|
14045
14052
|
default: { maxTemplates: 20, maxPayloadsPerTemplate: 3, multiTurn: false },
|
|
@@ -17395,36 +17402,6 @@ var SEVERITY_COUNT_COLOR = {
|
|
|
17395
17402
|
low: source_default.blue,
|
|
17396
17403
|
info: source_default.gray
|
|
17397
17404
|
};
|
|
17398
|
-
var BOX = {
|
|
17399
|
-
topLeft: "\u256D",
|
|
17400
|
-
topRight: "\u256E",
|
|
17401
|
-
bottomLeft: "\u2570",
|
|
17402
|
-
bottomRight: "\u256F",
|
|
17403
|
-
horizontal: "\u2500",
|
|
17404
|
-
vertical: "\u2502",
|
|
17405
|
-
teeRight: "\u251C",
|
|
17406
|
-
teeLeft: "\u2524"
|
|
17407
|
-
};
|
|
17408
|
-
function boxLine(width) {
|
|
17409
|
-
return BOX.horizontal.repeat(width);
|
|
17410
|
-
}
|
|
17411
|
-
function boxTop(width) {
|
|
17412
|
-
return ` ${source_default.gray(BOX.topLeft + boxLine(width) + BOX.topRight)}`;
|
|
17413
|
-
}
|
|
17414
|
-
function boxBottom(width) {
|
|
17415
|
-
return ` ${source_default.gray(BOX.bottomLeft + boxLine(width) + BOX.bottomRight)}`;
|
|
17416
|
-
}
|
|
17417
|
-
function boxRow(content, width) {
|
|
17418
|
-
const visible = stripAnsi2(content);
|
|
17419
|
-
const pad = Math.max(0, width - visible.length);
|
|
17420
|
-
return ` ${source_default.gray(BOX.vertical)} ${content}${" ".repeat(pad)}${source_default.gray(BOX.vertical)}`;
|
|
17421
|
-
}
|
|
17422
|
-
function boxDivider(width) {
|
|
17423
|
-
return ` ${source_default.gray(BOX.teeRight + boxLine(width) + BOX.teeLeft)}`;
|
|
17424
|
-
}
|
|
17425
|
-
function stripAnsi2(s) {
|
|
17426
|
-
return s.replace(/\x1b\[[0-9;]*m/g, "");
|
|
17427
|
-
}
|
|
17428
17405
|
function formatTerminal(report) {
|
|
17429
17406
|
const W3 = 60;
|
|
17430
17407
|
const lines = [];
|
|
@@ -17459,20 +17436,18 @@ function formatTerminal(report) {
|
|
|
17459
17436
|
}
|
|
17460
17437
|
}
|
|
17461
17438
|
lines.push("");
|
|
17462
|
-
lines.push(
|
|
17463
|
-
lines.push(
|
|
17464
|
-
lines.push(boxDivider(W3));
|
|
17439
|
+
lines.push(` ${source_default.gray("\u2500".repeat(50))}`);
|
|
17440
|
+
lines.push("");
|
|
17465
17441
|
const { summary } = report;
|
|
17466
|
-
const
|
|
17467
|
-
|
|
17468
|
-
|
|
17469
|
-
|
|
17470
|
-
|
|
17471
|
-
|
|
17472
|
-
|
|
17473
|
-
|
|
17474
|
-
lines.push(
|
|
17475
|
-
lines.push(boxBottom(W3));
|
|
17442
|
+
const sev = [
|
|
17443
|
+
summary.critical > 0 ? source_default.red.bold(`${summary.critical} critical`) : source_default.gray(`${summary.critical} critical`),
|
|
17444
|
+
summary.high > 0 ? source_default.hex("#f97316").bold(`${summary.high} high`) : source_default.gray(`${summary.high} high`),
|
|
17445
|
+
summary.medium > 0 ? source_default.yellow.bold(`${summary.medium} medium`) : source_default.gray(`${summary.medium} medium`),
|
|
17446
|
+
source_default.gray(`${summary.low} low`),
|
|
17447
|
+
source_default.gray(`${summary.info} info`)
|
|
17448
|
+
].join(source_default.gray(" "));
|
|
17449
|
+
lines.push(` ${sev}`);
|
|
17450
|
+
lines.push(` ${source_default.white.bold(String(summary.totalFindings))} findings ${source_default.gray("in")} ${source_default.white(formatDuration(report.durationMs))}`);
|
|
17476
17451
|
lines.push("");
|
|
17477
17452
|
return lines.join("\n");
|
|
17478
17453
|
}
|
|
@@ -17497,17 +17472,6 @@ function formatFinding(finding) {
|
|
|
17497
17472
|
lines.push("");
|
|
17498
17473
|
return lines.join("\n");
|
|
17499
17474
|
}
|
|
17500
|
-
function buildSeverityLine(summary) {
|
|
17501
|
-
const parts = [];
|
|
17502
|
-
const severities = ["critical", "high", "medium", "low", "info"];
|
|
17503
|
-
for (const sev of severities) {
|
|
17504
|
-
const count = summary[sev];
|
|
17505
|
-
const color = SEVERITY_COUNT_COLOR[sev];
|
|
17506
|
-
const icon = SEVERITY_STYLE[sev].icon;
|
|
17507
|
-
parts.push(` ${color(icon)} ${color(String(count))} ${source_default.gray(SEVERITY_STYLE[sev].label)}`);
|
|
17508
|
-
}
|
|
17509
|
-
return parts.join(source_default.gray(" "));
|
|
17510
|
-
}
|
|
17511
17475
|
function formatCategory(cat) {
|
|
17512
17476
|
return cat.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
17513
17477
|
}
|
|
@@ -17628,21 +17592,21 @@ function severityBadge(severity) {
|
|
|
17628
17592
|
function sleep(ms) {
|
|
17629
17593
|
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
17630
17594
|
}
|
|
17631
|
-
function
|
|
17595
|
+
function stripAnsi2(s) {
|
|
17632
17596
|
return s.replace(/\x1b\[[0-9;]*m/g, "");
|
|
17633
17597
|
}
|
|
17634
17598
|
var BOX_WIDTH = 55;
|
|
17635
|
-
function
|
|
17599
|
+
function boxTop(label) {
|
|
17636
17600
|
const inner = ` ${label} `;
|
|
17637
17601
|
const remaining = BOX_WIDTH - inner.length - 1;
|
|
17638
17602
|
return source_default.dim("\u250C\u2500 ") + source_default.bold.white(label) + source_default.dim(" " + "\u2500".repeat(Math.max(0, remaining)) + "\u2510");
|
|
17639
17603
|
}
|
|
17640
|
-
function
|
|
17641
|
-
const visible =
|
|
17604
|
+
function boxRow(content) {
|
|
17605
|
+
const visible = stripAnsi2(content);
|
|
17642
17606
|
const pad = Math.max(0, BOX_WIDTH - visible.length - 2);
|
|
17643
17607
|
return source_default.dim("\u2502") + " " + content + " ".repeat(pad) + source_default.dim("\u2502");
|
|
17644
17608
|
}
|
|
17645
|
-
function
|
|
17609
|
+
function boxBottom(withArrow) {
|
|
17646
17610
|
if (withArrow) {
|
|
17647
17611
|
const half = Math.floor((BOX_WIDTH - 1) / 2);
|
|
17648
17612
|
const rest = BOX_WIDTH - half - 1;
|
|
@@ -17676,19 +17640,19 @@ function buildReplayLines(data) {
|
|
|
17676
17640
|
const MED = 75;
|
|
17677
17641
|
const SLOW = 100;
|
|
17678
17642
|
const PAUSE = 200;
|
|
17679
|
-
lines.push({ text:
|
|
17643
|
+
lines.push({ text: boxTop("DISCOVER"), delay: PAUSE });
|
|
17680
17644
|
if (data.targetInfo) {
|
|
17681
17645
|
const t2 = data.targetInfo;
|
|
17682
17646
|
const truncUrl = t2.url.length > 30 ? t2.url.slice(0, 27) + "..." : t2.url;
|
|
17683
17647
|
lines.push({
|
|
17684
|
-
text:
|
|
17648
|
+
text: boxRow(
|
|
17685
17649
|
source_default.dim("\u25B8") + " " + source_default.white(`GET ${truncUrl}`) + source_default.dim(" \u2192 ") + source_default.white(`200`) + source_default.gray(` (${t2.type} endpoint detected)`)
|
|
17686
17650
|
),
|
|
17687
17651
|
delay: MED
|
|
17688
17652
|
});
|
|
17689
17653
|
if (t2.systemPrompt) {
|
|
17690
17654
|
lines.push({
|
|
17691
|
-
text:
|
|
17655
|
+
text: boxRow(
|
|
17692
17656
|
source_default.dim("\u25B8") + " " + source_default.white(`System prompt extracted`) + source_default.gray(` (${t2.systemPrompt.length} chars)`)
|
|
17693
17657
|
),
|
|
17694
17658
|
delay: MED
|
|
@@ -17696,7 +17660,7 @@ function buildReplayLines(data) {
|
|
|
17696
17660
|
}
|
|
17697
17661
|
if (t2.detectedFeatures && t2.detectedFeatures.length > 0) {
|
|
17698
17662
|
lines.push({
|
|
17699
|
-
text:
|
|
17663
|
+
text: boxRow(
|
|
17700
17664
|
source_default.dim("\u25B8") + " " + source_default.white(`${t2.detectedFeatures.length} features detected: `) + source_default.gray(t2.detectedFeatures.slice(0, 3).join(", "))
|
|
17701
17665
|
),
|
|
17702
17666
|
delay: MED
|
|
@@ -17704,7 +17668,7 @@ function buildReplayLines(data) {
|
|
|
17704
17668
|
}
|
|
17705
17669
|
if (t2.endpoints && t2.endpoints.length > 0) {
|
|
17706
17670
|
lines.push({
|
|
17707
|
-
text:
|
|
17671
|
+
text: boxRow(
|
|
17708
17672
|
source_default.dim("\u25B8") + " " + source_default.white(`${t2.endpoints.length} endpoints found`)
|
|
17709
17673
|
),
|
|
17710
17674
|
delay: MED
|
|
@@ -17713,15 +17677,15 @@ function buildReplayLines(data) {
|
|
|
17713
17677
|
} else {
|
|
17714
17678
|
const truncTarget = data.target.length > 30 ? data.target.slice(0, 27) + "..." : data.target;
|
|
17715
17679
|
lines.push({
|
|
17716
|
-
text:
|
|
17680
|
+
text: boxRow(
|
|
17717
17681
|
source_default.dim("\u25B8") + " " + source_default.white(`GET ${truncTarget}`) + source_default.dim(" \u2192 ") + source_default.white("200") + source_default.gray(" (LLM endpoint detected)")
|
|
17718
17682
|
),
|
|
17719
17683
|
delay: MED
|
|
17720
17684
|
});
|
|
17721
17685
|
}
|
|
17722
|
-
lines.push({ text:
|
|
17686
|
+
lines.push({ text: boxBottom(true), delay: FAST });
|
|
17723
17687
|
lines.push({ text: connector(), delay: PAUSE });
|
|
17724
|
-
lines.push({ text:
|
|
17688
|
+
lines.push({ text: boxTop("ATTACK"), delay: PAUSE });
|
|
17725
17689
|
const vulnerableFindings = data.findings.filter(
|
|
17726
17690
|
(f) => f.status !== "false-positive"
|
|
17727
17691
|
);
|
|
@@ -17733,7 +17697,7 @@ function buildReplayLines(data) {
|
|
|
17733
17697
|
if (cat === "system-prompt-extraction") outcome = "LEAKED";
|
|
17734
17698
|
if (cat === "jailbreak") outcome = "BYPASSED";
|
|
17735
17699
|
lines.push({
|
|
17736
|
-
text:
|
|
17700
|
+
text: boxRow(
|
|
17737
17701
|
source_default.dim("\u25B8") + " " + source_default.white(truncTitle) + source_default.dim(" \u2192 ") + " " + outcomeLabel(outcome.toLowerCase())
|
|
17738
17702
|
),
|
|
17739
17703
|
delay: MED
|
|
@@ -17741,7 +17705,7 @@ function buildReplayLines(data) {
|
|
|
17741
17705
|
}
|
|
17742
17706
|
if (vulnerableFindings.length > 8) {
|
|
17743
17707
|
lines.push({
|
|
17744
|
-
text:
|
|
17708
|
+
text: boxRow(
|
|
17745
17709
|
source_default.gray(
|
|
17746
17710
|
` ... and ${vulnerableFindings.length - 8} more attacks`
|
|
17747
17711
|
)
|
|
@@ -17751,15 +17715,15 @@ function buildReplayLines(data) {
|
|
|
17751
17715
|
}
|
|
17752
17716
|
} else {
|
|
17753
17717
|
lines.push({
|
|
17754
|
-
text:
|
|
17718
|
+
text: boxRow(
|
|
17755
17719
|
source_default.dim("\u25B8") + " " + source_default.white(`${data.summary.totalAttacks} probes executed`) + source_default.dim(" \u2192 ") + source_default.green("ALL SAFE")
|
|
17756
17720
|
),
|
|
17757
17721
|
delay: MED
|
|
17758
17722
|
});
|
|
17759
17723
|
}
|
|
17760
|
-
lines.push({ text:
|
|
17724
|
+
lines.push({ text: boxBottom(true), delay: FAST });
|
|
17761
17725
|
lines.push({ text: connector(), delay: PAUSE });
|
|
17762
|
-
lines.push({ text:
|
|
17726
|
+
lines.push({ text: boxTop("VERIFY"), delay: PAUSE });
|
|
17763
17727
|
const confirmed = data.findings.filter(
|
|
17764
17728
|
(f) => f.status === "confirmed" || f.status === "verified" || f.status === "scored" || f.status === "reported"
|
|
17765
17729
|
);
|
|
@@ -17769,7 +17733,7 @@ function buildReplayLines(data) {
|
|
|
17769
17733
|
if (confirmed.length > 0 || data.findings.length > 0) {
|
|
17770
17734
|
const reproduced = confirmed.length > 0 ? confirmed.length : data.findings.length;
|
|
17771
17735
|
lines.push({
|
|
17772
|
-
text:
|
|
17736
|
+
text: boxRow(
|
|
17773
17737
|
source_default.green("\u2713") + " " + source_default.white(`Reproduced ${reproduced}/${reproduced} findings`)
|
|
17774
17738
|
),
|
|
17775
17739
|
delay: MED
|
|
@@ -17777,7 +17741,7 @@ function buildReplayLines(data) {
|
|
|
17777
17741
|
}
|
|
17778
17742
|
if (falsePositives.length > 0) {
|
|
17779
17743
|
lines.push({
|
|
17780
|
-
text:
|
|
17744
|
+
text: boxRow(
|
|
17781
17745
|
source_default.red("\u2717") + " " + source_default.white(`Eliminated ${falsePositives.length} false positives`)
|
|
17782
17746
|
),
|
|
17783
17747
|
delay: MED
|
|
@@ -17785,13 +17749,13 @@ function buildReplayLines(data) {
|
|
|
17785
17749
|
}
|
|
17786
17750
|
if (confirmed.length === 0 && falsePositives.length === 0 && data.findings.length === 0) {
|
|
17787
17751
|
lines.push({
|
|
17788
|
-
text:
|
|
17752
|
+
text: boxRow(source_default.green("\u2713") + " " + source_default.white("No findings to verify")),
|
|
17789
17753
|
delay: MED
|
|
17790
17754
|
});
|
|
17791
17755
|
}
|
|
17792
|
-
lines.push({ text:
|
|
17756
|
+
lines.push({ text: boxBottom(true), delay: FAST });
|
|
17793
17757
|
lines.push({ text: connector(), delay: PAUSE });
|
|
17794
|
-
lines.push({ text:
|
|
17758
|
+
lines.push({ text: boxTop("REPORT"), delay: PAUSE });
|
|
17795
17759
|
const totalFindings = data.summary.totalFindings;
|
|
17796
17760
|
if (totalFindings > 0) {
|
|
17797
17761
|
const parts = [];
|
|
@@ -17801,25 +17765,25 @@ function buildReplayLines(data) {
|
|
|
17801
17765
|
if (data.summary.low > 0) parts.push(source_default.blue(`${data.summary.low} LOW`));
|
|
17802
17766
|
if (data.summary.info > 0) parts.push(source_default.gray(`${data.summary.info} INFO`));
|
|
17803
17767
|
lines.push({
|
|
17804
|
-
text:
|
|
17768
|
+
text: boxRow(
|
|
17805
17769
|
source_default.white(`${totalFindings} verified findings: `) + parts.join(source_default.dim(", "))
|
|
17806
17770
|
),
|
|
17807
17771
|
delay: MED
|
|
17808
17772
|
});
|
|
17809
17773
|
} else {
|
|
17810
17774
|
lines.push({
|
|
17811
|
-
text:
|
|
17775
|
+
text: boxRow(source_default.green.bold("0 findings") + source_default.white(" - target appears secure")),
|
|
17812
17776
|
delay: MED
|
|
17813
17777
|
});
|
|
17814
17778
|
}
|
|
17815
17779
|
const duration = data.durationMs < 1e3 ? `${data.durationMs}ms` : `${(data.durationMs / 1e3).toFixed(1)}s`;
|
|
17816
17780
|
lines.push({
|
|
17817
|
-
text:
|
|
17781
|
+
text: boxRow(
|
|
17818
17782
|
source_default.white(`Completed in ${duration}`) + source_default.dim(" \u2192 ") + source_default.gray("./pwnkit-report.json")
|
|
17819
17783
|
),
|
|
17820
17784
|
delay: MED
|
|
17821
17785
|
});
|
|
17822
|
-
lines.push({ text:
|
|
17786
|
+
lines.push({ text: boxBottom(false), delay: FAST });
|
|
17823
17787
|
return lines;
|
|
17824
17788
|
}
|
|
17825
17789
|
async function renderReplay(data) {
|
|
@@ -18197,7 +18161,7 @@ program2.command("scan").description("Run security scan against an LLM endpoint"
|
|
|
18197
18161
|
if (format !== "terminal") return;
|
|
18198
18162
|
switch (event.type) {
|
|
18199
18163
|
case "stage:start":
|
|
18200
|
-
|
|
18164
|
+
{
|
|
18201
18165
|
const msg = event.message;
|
|
18202
18166
|
if (msg.startsWith("Reading ")) {
|
|
18203
18167
|
spinner?.stop();
|
|
@@ -18209,16 +18173,8 @@ program2.command("scan").description("Run security scan against an LLM endpoint"
|
|
|
18209
18173
|
spinner?.start();
|
|
18210
18174
|
} else {
|
|
18211
18175
|
spinner?.update(msg);
|
|
18176
|
+
spinner?.start();
|
|
18212
18177
|
}
|
|
18213
|
-
} else if (event.stage === "attack") {
|
|
18214
|
-
const match = event.message.match(/(\d+)/);
|
|
18215
|
-
if (match) attackTotal = parseInt(match[1], 10);
|
|
18216
|
-
attacksDone = 0;
|
|
18217
|
-
spinner?.update(`Running attacks ${renderProgressBar(0, attackTotal || 1)}`);
|
|
18218
|
-
spinner?.start();
|
|
18219
|
-
} else {
|
|
18220
|
-
spinner?.update(event.message);
|
|
18221
|
-
spinner?.start();
|
|
18222
18178
|
}
|
|
18223
18179
|
break;
|
|
18224
18180
|
case "attack:end":
|
|
@@ -18241,11 +18197,11 @@ program2.command("scan").description("Run security scan against an LLM endpoint"
|
|
|
18241
18197
|
}
|
|
18242
18198
|
break;
|
|
18243
18199
|
case "finding":
|
|
18244
|
-
|
|
18245
|
-
|
|
18246
|
-
|
|
18247
|
-
|
|
18248
|
-
|
|
18200
|
+
spinner?.stop();
|
|
18201
|
+
console.log(
|
|
18202
|
+
` ${source_default.yellow("\u26A1")} ${source_default.yellow(event.message)}`
|
|
18203
|
+
);
|
|
18204
|
+
spinner?.start();
|
|
18249
18205
|
break;
|
|
18250
18206
|
case "error":
|
|
18251
18207
|
spinner?.fail(event.message);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pwnkit-cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.6",
|
|
5
5
|
"description": "AI-powered agentic security scanner. Scan endpoints, audit packages, review source code. Autonomous agents discover, attack, verify, and report.",
|
|
6
6
|
"bin": {
|
|
7
7
|
"pwnkit": "dist/index.js"
|