guardlink 1.4.1 → 1.4.3
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 +111 -7
- package/README.md +53 -5
- package/dist/agents/config.d.ts +7 -0
- package/dist/agents/config.d.ts.map +1 -1
- package/dist/agents/config.js.map +1 -1
- package/dist/agents/index.d.ts +9 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +36 -1
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/launcher.d.ts.map +1 -1
- package/dist/agents/launcher.js +5 -0
- package/dist/agents/launcher.js.map +1 -1
- package/dist/agents/prompts.d.ts +16 -1
- package/dist/agents/prompts.d.ts.map +1 -1
- package/dist/agents/prompts.js +511 -16
- package/dist/agents/prompts.js.map +1 -1
- package/dist/analyze/format.d.ts +72 -0
- package/dist/analyze/format.d.ts.map +1 -0
- package/dist/analyze/format.js +176 -0
- package/dist/analyze/format.js.map +1 -0
- package/dist/analyze/index.d.ts +76 -0
- package/dist/analyze/index.d.ts.map +1 -1
- package/dist/analyze/index.js +165 -2
- package/dist/analyze/index.js.map +1 -1
- package/dist/analyze/prompts.d.ts +3 -2
- package/dist/analyze/prompts.d.ts.map +1 -1
- package/dist/analyze/prompts.js +17 -3
- package/dist/analyze/prompts.js.map +1 -1
- package/dist/analyzer/sarif.d.ts +3 -2
- package/dist/analyzer/sarif.d.ts.map +1 -1
- package/dist/analyzer/sarif.js +29 -3
- package/dist/analyzer/sarif.js.map +1 -1
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +408 -37
- package/dist/cli/index.js.map +1 -1
- package/dist/dashboard/data.d.ts +11 -0
- package/dist/dashboard/data.d.ts.map +1 -1
- package/dist/dashboard/data.js +12 -0
- package/dist/dashboard/data.js.map +1 -1
- package/dist/dashboard/diagrams.d.ts +81 -12
- package/dist/dashboard/diagrams.d.ts.map +1 -1
- package/dist/dashboard/diagrams.js +750 -362
- package/dist/dashboard/diagrams.js.map +1 -1
- package/dist/dashboard/generate.d.ts +5 -2
- package/dist/dashboard/generate.d.ts.map +1 -1
- package/dist/dashboard/generate.js +2516 -244
- package/dist/dashboard/generate.js.map +1 -1
- package/dist/diff/engine.d.ts +2 -1
- package/dist/diff/engine.d.ts.map +1 -1
- package/dist/diff/engine.js +3 -2
- package/dist/diff/engine.js.map +1 -1
- package/dist/diff/git.js +3 -3
- package/dist/diff/git.js.map +1 -1
- package/dist/init/index.d.ts +7 -0
- package/dist/init/index.d.ts.map +1 -1
- package/dist/init/index.js +82 -27
- package/dist/init/index.js.map +1 -1
- package/dist/init/migrate.d.ts +39 -0
- package/dist/init/migrate.d.ts.map +1 -0
- package/dist/init/migrate.js +45 -0
- package/dist/init/migrate.js.map +1 -0
- package/dist/init/templates.d.ts +8 -0
- package/dist/init/templates.d.ts.map +1 -1
- package/dist/init/templates.js +68 -6
- package/dist/init/templates.js.map +1 -1
- package/dist/mcp/lookup.d.ts +1 -0
- package/dist/mcp/lookup.d.ts.map +1 -1
- package/dist/mcp/lookup.js +138 -10
- package/dist/mcp/lookup.js.map +1 -1
- package/dist/mcp/server.d.ts +2 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +32 -15
- package/dist/mcp/server.js.map +1 -1
- package/dist/parser/clear.d.ts +2 -1
- package/dist/parser/clear.d.ts.map +1 -1
- package/dist/parser/clear.js +19 -29
- package/dist/parser/clear.js.map +1 -1
- package/dist/parser/comment-strip.d.ts +5 -0
- package/dist/parser/comment-strip.d.ts.map +1 -1
- package/dist/parser/comment-strip.js +8 -0
- package/dist/parser/comment-strip.js.map +1 -1
- package/dist/parser/feature-filter.d.ts +42 -0
- package/dist/parser/feature-filter.d.ts.map +1 -0
- package/dist/parser/feature-filter.js +109 -0
- package/dist/parser/feature-filter.js.map +1 -0
- package/dist/parser/format.d.ts +24 -0
- package/dist/parser/format.d.ts.map +1 -0
- package/dist/parser/format.js +29 -0
- package/dist/parser/format.js.map +1 -0
- package/dist/parser/index.d.ts +2 -0
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/parser/index.js +1 -0
- package/dist/parser/index.js.map +1 -1
- package/dist/parser/parse-file.d.ts +1 -0
- package/dist/parser/parse-file.d.ts.map +1 -1
- package/dist/parser/parse-file.js +34 -9
- package/dist/parser/parse-file.js.map +1 -1
- package/dist/parser/parse-line.d.ts +9 -0
- package/dist/parser/parse-line.d.ts.map +1 -1
- package/dist/parser/parse-line.js +100 -26
- package/dist/parser/parse-line.js.map +1 -1
- package/dist/parser/parse-project.d.ts +1 -0
- package/dist/parser/parse-project.d.ts.map +1 -1
- package/dist/parser/parse-project.js +36 -2
- package/dist/parser/parse-project.js.map +1 -1
- package/dist/parser/validate.d.ts +3 -0
- package/dist/parser/validate.d.ts.map +1 -1
- package/dist/parser/validate.js +7 -0
- package/dist/parser/validate.js.map +1 -1
- package/dist/report/index.d.ts +1 -0
- package/dist/report/index.d.ts.map +1 -1
- package/dist/report/index.js +1 -0
- package/dist/report/index.js.map +1 -1
- package/dist/report/report.d.ts.map +1 -1
- package/dist/report/report.js +924 -24
- package/dist/report/report.js.map +1 -1
- package/dist/report/sequence.d.ts +11 -0
- package/dist/report/sequence.d.ts.map +1 -0
- package/dist/report/sequence.js +140 -0
- package/dist/report/sequence.js.map +1 -0
- package/dist/review/index.d.ts +3 -1
- package/dist/review/index.d.ts.map +1 -1
- package/dist/review/index.js +77 -35
- package/dist/review/index.js.map +1 -1
- package/dist/tui/commands.d.ts +1 -0
- package/dist/tui/commands.d.ts.map +1 -1
- package/dist/tui/commands.js +98 -12
- package/dist/tui/commands.js.map +1 -1
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +7 -2
- package/dist/tui/index.js.map +1 -1
- package/dist/types/index.d.ts +59 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/workspace/merge.d.ts.map +1 -1
- package/dist/workspace/merge.js +6 -2
- package/dist/workspace/merge.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/agents/prompts.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/agents/prompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GuardLink — Pentest finding format helpers.
|
|
3
|
+
*
|
|
4
|
+
* Defensive normalizers for fields whose shape varies across CXG versions
|
|
5
|
+
* and template authors. Keep these tiny and pure — no I/O, no side effects.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Render a confidence value for display, regardless of how the upstream
|
|
9
|
+
* scanner emitted it.
|
|
10
|
+
*
|
|
11
|
+
* CXG output has historically emitted confidence in three different shapes:
|
|
12
|
+
* - integer percentage (most current versions): `50` → `"50%"`
|
|
13
|
+
* - severity-style string (some templates pre-normalization): `"high"` → `"HIGH"`
|
|
14
|
+
* - missing / null / undefined (older or partial scans): → `"—"`
|
|
15
|
+
*
|
|
16
|
+
* Returns a display string that's safe to drop into HTML or terminal output.
|
|
17
|
+
* Never throws — always returns *something* renderable.
|
|
18
|
+
*/
|
|
19
|
+
export declare function formatConfidence(value: unknown): string;
|
|
20
|
+
/**
|
|
21
|
+
* Mirrors the shape of the `evidence` slot on a PentestFinding without
|
|
22
|
+
* pulling the full PentestFinding type from src/analyze/index.ts (would
|
|
23
|
+
* create a circular import). Any object matching this structural shape
|
|
24
|
+
* can be passed to redactEvidence().
|
|
25
|
+
*/
|
|
26
|
+
export interface EvidenceLike {
|
|
27
|
+
request: string | null;
|
|
28
|
+
response: string | null;
|
|
29
|
+
matched_patterns: string[];
|
|
30
|
+
data: Record<string, unknown>;
|
|
31
|
+
timestamp?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Surgical redactor for sensitive tokens. Designed to preserve the
|
|
35
|
+
* confirmation evidence of a pentest finding while removing material that
|
|
36
|
+
* would enable replay attacks if a screenshot or exported HTML escaped the
|
|
37
|
+
* customer's perimeter.
|
|
38
|
+
*
|
|
39
|
+
* The principle: redact what enables replay, keep what proves the exploit.
|
|
40
|
+
*
|
|
41
|
+
* Patterns:
|
|
42
|
+
* - JWT (eyJ-prefixed three-segment): keep header and payload (the
|
|
43
|
+
* claims — these are the proof of what role/scope/sub was achieved),
|
|
44
|
+
* replace the signature segment with `<signature-redacted>`. Anyone
|
|
45
|
+
* screenshotting can still decode the payload at jwt.io to see the
|
|
46
|
+
* claims; nobody can replay the token because the signature is gone.
|
|
47
|
+
* - Authorization: Bearer <jwt>: same JWT split rule.
|
|
48
|
+
* - Authorization: Bearer <opaque>: show first 4 + last 4 chars only,
|
|
49
|
+
* enough for correlation/fingerprinting but not replay.
|
|
50
|
+
* - Authorization: Basic|Digest|NTLM <value>: fully replace value with
|
|
51
|
+
* `<redacted>`. These ARE the credential — no useful prefix.
|
|
52
|
+
* - JSON credential fields (password, api_key, access_token, etc.):
|
|
53
|
+
* keep field name (structural proof that the request used this
|
|
54
|
+
* credential type), replace value with `<redacted>`.
|
|
55
|
+
* - Query-string credentials: same — keep field name, redact value.
|
|
56
|
+
* - Cookie / Set-Cookie values: keep cookie name (proves session-based
|
|
57
|
+
* auth was used), redact value.
|
|
58
|
+
*
|
|
59
|
+
* Idempotent: re-running on already-redacted output is a no-op since the
|
|
60
|
+
* redaction markers themselves don't match any of the input patterns.
|
|
61
|
+
*
|
|
62
|
+
* Returns input unchanged for null / undefined / empty / non-string.
|
|
63
|
+
*/
|
|
64
|
+
export declare function redactSensitiveTokens(text: string | null | undefined): string | null | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* Redacts an entire `evidence` object — request, response, and the
|
|
67
|
+
* unstructured `data` field. Returns a new object; does not mutate the
|
|
68
|
+
* input. Non-string fields (matched_patterns, timestamp) pass through
|
|
69
|
+
* unchanged since they don't carry secret material.
|
|
70
|
+
*/
|
|
71
|
+
export declare function redactEvidence(ev: EvidenceLike): EvidenceLike;
|
|
72
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/analyze/format.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CA8BvD;AAYD;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAsEhG;AAgCD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,YAAY,GAAG,YAAY,CAQ7D"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GuardLink — Pentest finding format helpers.
|
|
3
|
+
*
|
|
4
|
+
* Defensive normalizers for fields whose shape varies across CXG versions
|
|
5
|
+
* and template authors. Keep these tiny and pure — no I/O, no side effects.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Render a confidence value for display, regardless of how the upstream
|
|
9
|
+
* scanner emitted it.
|
|
10
|
+
*
|
|
11
|
+
* CXG output has historically emitted confidence in three different shapes:
|
|
12
|
+
* - integer percentage (most current versions): `50` → `"50%"`
|
|
13
|
+
* - severity-style string (some templates pre-normalization): `"high"` → `"HIGH"`
|
|
14
|
+
* - missing / null / undefined (older or partial scans): → `"—"`
|
|
15
|
+
*
|
|
16
|
+
* Returns a display string that's safe to drop into HTML or terminal output.
|
|
17
|
+
* Never throws — always returns *something* renderable.
|
|
18
|
+
*/
|
|
19
|
+
export function formatConfidence(value) {
|
|
20
|
+
if (value === null || value === undefined || value === '')
|
|
21
|
+
return '—';
|
|
22
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
23
|
+
// Clamp into [0, 100] so a malformed `150` doesn't print "150%".
|
|
24
|
+
const clamped = Math.max(0, Math.min(100, Math.round(value)));
|
|
25
|
+
return `${clamped}%`;
|
|
26
|
+
}
|
|
27
|
+
if (typeof value === 'string') {
|
|
28
|
+
const trimmed = value.trim();
|
|
29
|
+
if (!trimmed)
|
|
30
|
+
return '—';
|
|
31
|
+
// String might still be numeric: "50" or "50%"
|
|
32
|
+
const numericMatch = trimmed.match(/^(-?\d+(?:\.\d+)?)\s*%?$/);
|
|
33
|
+
if (numericMatch) {
|
|
34
|
+
const n = Number.parseFloat(numericMatch[1]);
|
|
35
|
+
if (Number.isFinite(n)) {
|
|
36
|
+
const clamped = Math.max(0, Math.min(100, Math.round(n)));
|
|
37
|
+
return `${clamped}%`;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Severity-word style — uppercase for visual weight, no other transform.
|
|
41
|
+
return trimmed.toUpperCase();
|
|
42
|
+
}
|
|
43
|
+
// Anything else (boolean, object, array) — render the placeholder rather
|
|
44
|
+
// than letting `[object Object]` leak into the dashboard.
|
|
45
|
+
return '—';
|
|
46
|
+
}
|
|
47
|
+
/* ── Evidence redaction (bug #11) ──────────────────────────────────── */
|
|
48
|
+
/** Credential field-name pattern used for both string-form (JSON / query
|
|
49
|
+
* string) matching and object-form key inspection. Includes bare `token`
|
|
50
|
+
* because it's a common session/CSRF/auth token name. */
|
|
51
|
+
const CREDENTIAL_FIELD_PATTERN = '(?:password|passwd|pwd|secret|api[_-]?key|apiKey|access[_-]?token|accessToken|refresh[_-]?token|refreshToken|token)';
|
|
52
|
+
/** Regex form for key-name testing — anchored, case-insensitive. */
|
|
53
|
+
const CREDENTIAL_KEY_RE = new RegExp(`^${CREDENTIAL_FIELD_PATTERN}$`, 'i');
|
|
54
|
+
/**
|
|
55
|
+
* Surgical redactor for sensitive tokens. Designed to preserve the
|
|
56
|
+
* confirmation evidence of a pentest finding while removing material that
|
|
57
|
+
* would enable replay attacks if a screenshot or exported HTML escaped the
|
|
58
|
+
* customer's perimeter.
|
|
59
|
+
*
|
|
60
|
+
* The principle: redact what enables replay, keep what proves the exploit.
|
|
61
|
+
*
|
|
62
|
+
* Patterns:
|
|
63
|
+
* - JWT (eyJ-prefixed three-segment): keep header and payload (the
|
|
64
|
+
* claims — these are the proof of what role/scope/sub was achieved),
|
|
65
|
+
* replace the signature segment with `<signature-redacted>`. Anyone
|
|
66
|
+
* screenshotting can still decode the payload at jwt.io to see the
|
|
67
|
+
* claims; nobody can replay the token because the signature is gone.
|
|
68
|
+
* - Authorization: Bearer <jwt>: same JWT split rule.
|
|
69
|
+
* - Authorization: Bearer <opaque>: show first 4 + last 4 chars only,
|
|
70
|
+
* enough for correlation/fingerprinting but not replay.
|
|
71
|
+
* - Authorization: Basic|Digest|NTLM <value>: fully replace value with
|
|
72
|
+
* `<redacted>`. These ARE the credential — no useful prefix.
|
|
73
|
+
* - JSON credential fields (password, api_key, access_token, etc.):
|
|
74
|
+
* keep field name (structural proof that the request used this
|
|
75
|
+
* credential type), replace value with `<redacted>`.
|
|
76
|
+
* - Query-string credentials: same — keep field name, redact value.
|
|
77
|
+
* - Cookie / Set-Cookie values: keep cookie name (proves session-based
|
|
78
|
+
* auth was used), redact value.
|
|
79
|
+
*
|
|
80
|
+
* Idempotent: re-running on already-redacted output is a no-op since the
|
|
81
|
+
* redaction markers themselves don't match any of the input patterns.
|
|
82
|
+
*
|
|
83
|
+
* Returns input unchanged for null / undefined / empty / non-string.
|
|
84
|
+
*/
|
|
85
|
+
export function redactSensitiveTokens(text) {
|
|
86
|
+
if (text === null || text === undefined || text === '')
|
|
87
|
+
return text;
|
|
88
|
+
if (typeof text !== 'string')
|
|
89
|
+
return text;
|
|
90
|
+
let result = text;
|
|
91
|
+
// 1. JWTs: keep header.payload, redact signature.
|
|
92
|
+
// The \b anchors ensure dotted identifiers like App.Auth.Login don't match.
|
|
93
|
+
result = result.replace(/\b(eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+)\.[A-Za-z0-9_-]+\b/g, '$1.<signature-redacted>');
|
|
94
|
+
// 2. Authorization: Bearer <opaque token> (NOT a JWT — the JWT case was
|
|
95
|
+
// handled in step 1 already, so any Bearer value here is either opaque
|
|
96
|
+
// or a partial/malformed JWT). Negative lookahead `(?!eyJ)` skips
|
|
97
|
+
// JWT-shaped values. Min length 8 to avoid matching nothing-tokens.
|
|
98
|
+
result = result.replace(/(Authorization:\s*Bearer\s+)(?!eyJ)([A-Za-z0-9_\-\.=]{8,})/gi, (_match, prefix, token) => {
|
|
99
|
+
// First 4 + last 4 chars: fingerprint for correlation, no replay value.
|
|
100
|
+
const fingerprint = token.length > 12
|
|
101
|
+
? `${token.slice(0, 4)}...${token.slice(-4)}`
|
|
102
|
+
: '...';
|
|
103
|
+
return `${prefix}${fingerprint} <bearer-redacted>`;
|
|
104
|
+
});
|
|
105
|
+
// 3. Authorization: Basic / Digest / NTLM <value> — full redact.
|
|
106
|
+
// Match the whole value through to the end of the header line so multi-
|
|
107
|
+
// word Digest values (e.g. `Digest username="x", response="y"`) are
|
|
108
|
+
// redacted entirely, not just up to the first whitespace.
|
|
109
|
+
result = result.replace(/(Authorization:\s*(?:Basic|Digest|NTLM)\s+)[^\r\n]+/gi, (_match, prefix) => `${prefix}<redacted>`);
|
|
110
|
+
// 4. JSON credential fields: keep field name, redact value.
|
|
111
|
+
// Supports both snake_case (api_key) and camelCase (apiKey) variants.
|
|
112
|
+
// The value character class excludes `<` so values that already contain
|
|
113
|
+
// a redaction marker (e.g. a JWT split in step 1 produced
|
|
114
|
+
// `"token":"eyJ.eyJ.<signature-redacted>"`) don't get over-redacted —
|
|
115
|
+
// we'd otherwise wipe the preserved JWT payload here.
|
|
116
|
+
const credentialFieldNames = CREDENTIAL_FIELD_PATTERN;
|
|
117
|
+
result = result.replace(new RegExp(`("${credentialFieldNames}"\\s*:\\s*")(?:[^"\\\\<]|\\\\.)*(")`, 'gi'), (_match, prefix, suffix) => `${prefix}<redacted>${suffix}`);
|
|
118
|
+
// 5. Query-string credentials: name=value pairs.
|
|
119
|
+
// Stops at the typical separators (& ; whitespace , " ').
|
|
120
|
+
result = result.replace(new RegExp(`(\\b${credentialFieldNames}=)[^&\\s;,"']+`, 'gi'), (_match, prefix) => `${prefix}<redacted>`);
|
|
121
|
+
// 6. Cookie values: keep cookie name (the structural proof that
|
|
122
|
+
// cookie-based auth was used), redact value. Handles both `Set-Cookie:`
|
|
123
|
+
// response headers (with attributes like Path=, HttpOnly) and `Cookie:`
|
|
124
|
+
// request headers (semicolon-separated name=value pairs).
|
|
125
|
+
result = result.replace(/(Set-Cookie:\s*[^=;\s]+=)[^;\r\n]+/gi, (_match, prefix) => `${prefix}<redacted>`);
|
|
126
|
+
result = result.replace(/(Cookie:\s*[^=;\s]+=)[^;\r\n]+/gi, (_match, prefix) => `${prefix}<redacted>`);
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Recursively walks any value, applying redactSensitiveTokens to every
|
|
131
|
+
* string leaf. Used to scrub the unstructured `evidence.data` field where
|
|
132
|
+
* templates may place arbitrary scan output (extracted tokens, response
|
|
133
|
+
* bodies, captured headers).
|
|
134
|
+
*
|
|
135
|
+
* When walking an object, this function also inspects each key — if the
|
|
136
|
+
* key name matches a credential field (e.g. `api_key`, `password`), the
|
|
137
|
+
* value is replaced with `<redacted>` directly, regardless of its
|
|
138
|
+
* content. This catches the parsed-object form (`{api_key: "sk-live-..."}`)
|
|
139
|
+
* which the string-pattern matcher cannot see, since the key/value
|
|
140
|
+
* relationship is only visible structurally.
|
|
141
|
+
*/
|
|
142
|
+
function deepRedact(value) {
|
|
143
|
+
if (typeof value === 'string')
|
|
144
|
+
return redactSensitiveTokens(value);
|
|
145
|
+
if (Array.isArray(value))
|
|
146
|
+
return value.map(deepRedact);
|
|
147
|
+
if (value && typeof value === 'object') {
|
|
148
|
+
const out = {};
|
|
149
|
+
for (const [k, v] of Object.entries(value)) {
|
|
150
|
+
if (CREDENTIAL_KEY_RE.test(k) && typeof v === 'string') {
|
|
151
|
+
out[k] = '<redacted>';
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
out[k] = deepRedact(v);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return out;
|
|
158
|
+
}
|
|
159
|
+
return value;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Redacts an entire `evidence` object — request, response, and the
|
|
163
|
+
* unstructured `data` field. Returns a new object; does not mutate the
|
|
164
|
+
* input. Non-string fields (matched_patterns, timestamp) pass through
|
|
165
|
+
* unchanged since they don't carry secret material.
|
|
166
|
+
*/
|
|
167
|
+
export function redactEvidence(ev) {
|
|
168
|
+
return {
|
|
169
|
+
request: redactSensitiveTokens(ev.request) ?? null,
|
|
170
|
+
response: redactSensitiveTokens(ev.response) ?? null,
|
|
171
|
+
matched_patterns: ev.matched_patterns,
|
|
172
|
+
data: deepRedact(ev.data),
|
|
173
|
+
timestamp: ev.timestamp,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/analyze/format.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,GAAG,CAAC;IAEtE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACxD,iEAAiE;QACjE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9D,OAAO,GAAG,OAAO,GAAG,CAAC;IACvB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO;YAAE,OAAO,GAAG,CAAC;QAEzB,+CAA+C;QAC/C,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC/D,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7C,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC1D,OAAO,GAAG,OAAO,GAAG,CAAC;YACvB,CAAC;QACH,CAAC;QAED,yEAAyE;QACzE,OAAO,OAAO,CAAC,WAAW,EAAE,CAAC;IAC/B,CAAC;IAED,yEAAyE;IACzE,0DAA0D;IAC1D,OAAO,GAAG,CAAC;AACb,CAAC;AAED,0EAA0E;AAE1E;;0DAE0D;AAC1D,MAAM,wBAAwB,GAAG,qHAAqH,CAAC;AAEvJ,oEAAoE;AACpE,MAAM,iBAAiB,GAAG,IAAI,MAAM,CAAC,IAAI,wBAAwB,GAAG,EAAE,GAAG,CAAC,CAAC;AAgB3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAA+B;IACnE,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACpE,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE1C,IAAI,MAAM,GAAG,IAAI,CAAC;IAElB,kDAAkD;IAClD,+EAA+E;IAC/E,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,6DAA6D,EAC7D,yBAAyB,CAC1B,CAAC;IAEF,wEAAwE;IACxE,0EAA0E;IAC1E,qEAAqE;IACrE,uEAAuE;IACvE,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,8DAA8D,EAC9D,CAAC,MAAM,EAAE,MAAc,EAAE,KAAa,EAAE,EAAE;QACxC,wEAAwE;QACxE,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,GAAG,EAAE;YACnC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;YAC7C,CAAC,CAAC,KAAK,CAAC;QACV,OAAO,GAAG,MAAM,GAAG,WAAW,oBAAoB,CAAC;IACrD,CAAC,CACF,CAAC;IAEF,iEAAiE;IACjE,2EAA2E;IAC3E,uEAAuE;IACvE,6DAA6D;IAC7D,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,uDAAuD,EACvD,CAAC,MAAM,EAAE,MAAc,EAAE,EAAE,CAAC,GAAG,MAAM,YAAY,CAClD,CAAC;IAEF,4DAA4D;IAC5D,yEAAyE;IACzE,2EAA2E;IAC3E,6DAA6D;IAC7D,yEAAyE;IACzE,yDAAyD;IACzD,MAAM,oBAAoB,GAAG,wBAAwB,CAAC;IACtD,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,IAAI,MAAM,CAAC,KAAK,oBAAoB,qCAAqC,EAAE,IAAI,CAAC,EAChF,CAAC,MAAM,EAAE,MAAc,EAAE,MAAc,EAAE,EAAE,CAAC,GAAG,MAAM,aAAa,MAAM,EAAE,CAC3E,CAAC;IAEF,iDAAiD;IACjD,6DAA6D;IAC7D,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,IAAI,MAAM,CAAC,OAAO,oBAAoB,gBAAgB,EAAE,IAAI,CAAC,EAC7D,CAAC,MAAM,EAAE,MAAc,EAAE,EAAE,CAAC,GAAG,MAAM,YAAY,CAClD,CAAC;IAEF,gEAAgE;IAChE,2EAA2E;IAC3E,2EAA2E;IAC3E,6DAA6D;IAC7D,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,sCAAsC,EACtC,CAAC,MAAM,EAAE,MAAc,EAAE,EAAE,CAAC,GAAG,MAAM,YAAY,CAClD,CAAC;IACF,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,kCAAkC,EAClC,CAAC,MAAM,EAAE,MAAc,EAAE,EAAE,CAAC,GAAG,MAAM,YAAY,CAClD,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,qBAAqB,CAAC,KAAK,CAAC,CAAC;IACnE,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACvD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;YACtE,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBACvD,GAAG,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC;YACxB,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,EAAgB;IAC7C,OAAO;QACL,OAAO,EAAE,qBAAqB,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI;QAClD,QAAQ,EAAE,qBAAqB,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,IAAI;QACpD,gBAAgB,EAAE,EAAE,CAAC,gBAAgB;QACrC,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC,IAAI,CAA4B;QACpD,SAAS,EAAE,EAAE,CAAC,SAAS;KACxB,CAAC;AACJ,CAAC"}
|
package/dist/analyze/index.d.ts
CHANGED
|
@@ -113,4 +113,80 @@ export interface ThreatReportWithContent extends SavedThreatReport {
|
|
|
113
113
|
content: string;
|
|
114
114
|
}
|
|
115
115
|
export declare function loadThreatReportsForDashboard(root: string): ThreatReportWithContent[];
|
|
116
|
+
/**
|
|
117
|
+
* @flows PentestFindings -> #llm-client via readFileSync -- "Reads CXG scan results for dashboard and report context"
|
|
118
|
+
* @handles internal on #llm-client -- "Processes pentest scan output (JSON/SARIF)"
|
|
119
|
+
*/
|
|
120
|
+
export interface PentestFinding {
|
|
121
|
+
id: string;
|
|
122
|
+
target: string;
|
|
123
|
+
template_id: string;
|
|
124
|
+
severity: string;
|
|
125
|
+
/** CXG emits this in different shapes across versions: integer percentage,
|
|
126
|
+
* severity-style string ("high"), or missing entirely. Render via
|
|
127
|
+
* formatConfidence() rather than assuming a specific type. */
|
|
128
|
+
confidence: number | string | null;
|
|
129
|
+
title: string;
|
|
130
|
+
description: string;
|
|
131
|
+
evidence: {
|
|
132
|
+
request: string | null;
|
|
133
|
+
response: string | null;
|
|
134
|
+
matched_patterns: string[];
|
|
135
|
+
data: Record<string, unknown>;
|
|
136
|
+
timestamp?: string;
|
|
137
|
+
};
|
|
138
|
+
cve_ids: string[];
|
|
139
|
+
cwe_ids: string[];
|
|
140
|
+
cvss_score: number | null;
|
|
141
|
+
remediation: string;
|
|
142
|
+
references: string[];
|
|
143
|
+
tags: string[];
|
|
144
|
+
timestamp: string;
|
|
145
|
+
}
|
|
146
|
+
export interface PentestScanResult {
|
|
147
|
+
scan_id: string;
|
|
148
|
+
started_at: string;
|
|
149
|
+
completed_at: string;
|
|
150
|
+
findings: PentestFinding[];
|
|
151
|
+
statistics: {
|
|
152
|
+
targets_scanned: number;
|
|
153
|
+
templates_executed: number;
|
|
154
|
+
findings_by_severity: Record<string, number>;
|
|
155
|
+
success_rate: number;
|
|
156
|
+
duration?: {
|
|
157
|
+
secs: number;
|
|
158
|
+
nanos: number;
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
source_file: string;
|
|
162
|
+
}
|
|
163
|
+
export interface PentestTemplate {
|
|
164
|
+
filename: string;
|
|
165
|
+
id: string;
|
|
166
|
+
tags: string[];
|
|
167
|
+
severity: string;
|
|
168
|
+
language: string;
|
|
169
|
+
}
|
|
170
|
+
export interface PentestData {
|
|
171
|
+
scans: PentestScanResult[];
|
|
172
|
+
templates: PentestTemplate[];
|
|
173
|
+
totalFindings: number;
|
|
174
|
+
findingsBySeverity: Record<string, number>;
|
|
175
|
+
/** True when surgical evidence redaction was applied during load (because
|
|
176
|
+
* the project config has `redactEvidence: true`). Consumers can use this
|
|
177
|
+
* to render a visual indicator so users of the dashboard / report know
|
|
178
|
+
* whether they're seeing full or redacted evidence. See bug #11. */
|
|
179
|
+
redactionApplied?: boolean;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Load pentest findings from .guardlink/pentest-findings/ and template
|
|
183
|
+
* metadata from .guardlink/cxg-templates/.
|
|
184
|
+
*
|
|
185
|
+
* @mitigates #llm-client against #path-traversal using #path-validation -- "join() constrains reads to .guardlink/"
|
|
186
|
+
*/
|
|
187
|
+
export declare function loadPentestData(root: string): PentestData;
|
|
188
|
+
/**
|
|
189
|
+
* Serialize pentest findings into a compact text summary for LLM context.
|
|
190
|
+
*/
|
|
191
|
+
export declare function serializePentestFindings(data: PentestData): string;
|
|
116
192
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyze/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,KAAK,iBAAiB,EAAyD,MAAM,cAAc,CAAC;AAC7G,OAAO,EAAE,KAAK,SAAS,EAA+B,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyze/index.ts"],"names":[],"mappings":"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"}
|
package/dist/analyze/index.js
CHANGED
|
@@ -21,6 +21,8 @@ import { join, relative } from 'node:path';
|
|
|
21
21
|
import { FRAMEWORK_LABELS, FRAMEWORK_PROMPTS, buildUserMessage } from './prompts.js';
|
|
22
22
|
import { chatCompletion } from './llm.js';
|
|
23
23
|
import { GUARDLINK_TOOLS, createToolExecutor } from './tools.js';
|
|
24
|
+
import { formatConfidence, redactEvidence } from './format.js';
|
|
25
|
+
import { loadProjectConfig } from '../agents/config.js';
|
|
24
26
|
export { FRAMEWORK_LABELS, FRAMEWORK_PROMPTS, buildUserMessage } from './prompts.js';
|
|
25
27
|
export { buildConfig, autoDetectConfig } from './llm.js';
|
|
26
28
|
export { GUARDLINK_TOOLS, createToolExecutor } from './tools.js';
|
|
@@ -304,6 +306,13 @@ export function serializeModel(model) {
|
|
|
304
306
|
description: e.description,
|
|
305
307
|
file: e.location.file, line: e.location.line,
|
|
306
308
|
}));
|
|
309
|
+
if (model.confirmed.length)
|
|
310
|
+
compact.confirmed = model.confirmed.map(c => ({
|
|
311
|
+
threat: c.threat, asset: c.asset, severity: c.severity,
|
|
312
|
+
refs: c.external_refs.length ? c.external_refs : undefined,
|
|
313
|
+
description: c.description,
|
|
314
|
+
file: c.location.file, line: c.location.line,
|
|
315
|
+
}));
|
|
307
316
|
if (model.acceptances.length)
|
|
308
317
|
compact.acceptances = model.acceptances.map(a => ({
|
|
309
318
|
asset: a.asset, threat: a.threat, description: a.description,
|
|
@@ -401,7 +410,7 @@ export function serializeModelCompact(model) {
|
|
|
401
410
|
}
|
|
402
411
|
const compact = {
|
|
403
412
|
project: model.project,
|
|
404
|
-
summary: `${model.annotations_parsed} annotations, ${model.assets.length} assets, ${model.threats.length} threats, ${model.controls.length} controls, ${model.exposures.length} exposures (${unmitigated.length} unmitigated), ${model.mitigations.length} mitigations`,
|
|
413
|
+
summary: `${model.annotations_parsed} annotations, ${model.assets.length} assets, ${model.threats.length} threats, ${model.controls.length} controls, ${model.exposures.length} exposures (${unmitigated.length} unmitigated), ${model.confirmed.length} confirmed, ${model.mitigations.length} mitigations`,
|
|
405
414
|
severity_breakdown: sevCounts,
|
|
406
415
|
};
|
|
407
416
|
// Assets — just path + id, no descriptions
|
|
@@ -465,8 +474,10 @@ export async function generateThreatReport(opts) {
|
|
|
465
474
|
const modelJson = serializeModel(model);
|
|
466
475
|
const projectContext = buildProjectContext(root);
|
|
467
476
|
const codeSnippets = extractCodeSnippets(root, model, snippetContext, snippetBudget);
|
|
477
|
+
const pentestData = loadPentestData(root);
|
|
478
|
+
const pentestContext = serializePentestFindings(pentestData);
|
|
468
479
|
const systemPrompt = FRAMEWORK_PROMPTS[framework];
|
|
469
|
-
const userMessage = buildUserMessage(modelJson, framework, customPrompt, projectContext || undefined, codeSnippets || undefined);
|
|
480
|
+
const userMessage = buildUserMessage(modelJson, framework, customPrompt, projectContext || undefined, codeSnippets || undefined, pentestContext || undefined);
|
|
470
481
|
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
471
482
|
// Build enhanced config with optional upgrades
|
|
472
483
|
const enhancedConfig = { ...llmConfig };
|
|
@@ -579,4 +590,156 @@ export function loadThreatReportsForDashboard(root) {
|
|
|
579
590
|
}
|
|
580
591
|
return result;
|
|
581
592
|
}
|
|
593
|
+
const PENTEST_FINDINGS_DIR = 'pentest-findings';
|
|
594
|
+
const CXG_TEMPLATES_DIR = 'cxg-templates';
|
|
595
|
+
/**
|
|
596
|
+
* Load pentest findings from .guardlink/pentest-findings/ and template
|
|
597
|
+
* metadata from .guardlink/cxg-templates/.
|
|
598
|
+
*
|
|
599
|
+
* @mitigates #llm-client against #path-traversal using #path-validation -- "join() constrains reads to .guardlink/"
|
|
600
|
+
*/
|
|
601
|
+
export function loadPentestData(root) {
|
|
602
|
+
const data = { scans: [], templates: [], totalFindings: 0, findingsBySeverity: {} };
|
|
603
|
+
// Load scan results (JSON files)
|
|
604
|
+
const findingsDir = join(root, '.guardlink', PENTEST_FINDINGS_DIR);
|
|
605
|
+
if (existsSync(findingsDir)) {
|
|
606
|
+
try {
|
|
607
|
+
const files = readdirSync(findingsDir).filter(f => f.endsWith('.json'));
|
|
608
|
+
for (const file of files) {
|
|
609
|
+
try {
|
|
610
|
+
const raw = readFileSync(join(findingsDir, file), 'utf-8');
|
|
611
|
+
const parsed = JSON.parse(raw);
|
|
612
|
+
if (parsed.findings && Array.isArray(parsed.findings)) {
|
|
613
|
+
data.scans.push({ ...parsed, source_file: file });
|
|
614
|
+
data.totalFindings += parsed.findings.length;
|
|
615
|
+
for (const f of parsed.findings) {
|
|
616
|
+
const sev = (f.severity || 'unknown').toLowerCase();
|
|
617
|
+
data.findingsBySeverity[sev] = (data.findingsBySeverity[sev] || 0) + 1;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
catch { /* skip malformed JSON */ }
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
catch { /* dir not readable */ }
|
|
625
|
+
}
|
|
626
|
+
// Also check repo root for legacy guardlink-pentest.json
|
|
627
|
+
for (const name of ['guardlink-pentest.json']) {
|
|
628
|
+
const rootFile = join(root, name);
|
|
629
|
+
if (existsSync(rootFile)) {
|
|
630
|
+
try {
|
|
631
|
+
const raw = readFileSync(rootFile, 'utf-8');
|
|
632
|
+
const parsed = JSON.parse(raw);
|
|
633
|
+
if (parsed.findings && Array.isArray(parsed.findings)) {
|
|
634
|
+
const alreadyLoaded = data.scans.some(s => s.scan_id === parsed.scan_id);
|
|
635
|
+
if (!alreadyLoaded) {
|
|
636
|
+
data.scans.push({ ...parsed, source_file: name });
|
|
637
|
+
data.totalFindings += parsed.findings.length;
|
|
638
|
+
for (const f of parsed.findings) {
|
|
639
|
+
const sev = (f.severity || 'unknown').toLowerCase();
|
|
640
|
+
data.findingsBySeverity[sev] = (data.findingsBySeverity[sev] || 0) + 1;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
catch { /* skip */ }
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
// Sort scans newest first
|
|
649
|
+
data.scans.sort((a, b) => (b.completed_at || '').localeCompare(a.completed_at || ''));
|
|
650
|
+
// Bug #11: surgical evidence redaction. When the project config has
|
|
651
|
+
// `redactEvidence: true`, walk every finding and replace evidence
|
|
652
|
+
// request/response strings + the recursive `data` blob with redacted
|
|
653
|
+
// forms. Default is OFF — OSS users running against test targets
|
|
654
|
+
// (Juice Shop, their own staging) see full evidence. Enterprise
|
|
655
|
+
// customers with audit policies enable the flag once via
|
|
656
|
+
// `guardlink config set redact-evidence true`.
|
|
657
|
+
const projectConfig = loadProjectConfig(root);
|
|
658
|
+
if (projectConfig?.redactEvidence) {
|
|
659
|
+
for (const scan of data.scans) {
|
|
660
|
+
scan.findings = scan.findings.map((f) => ({
|
|
661
|
+
...f,
|
|
662
|
+
evidence: f.evidence ? redactEvidence(f.evidence) : f.evidence,
|
|
663
|
+
}));
|
|
664
|
+
}
|
|
665
|
+
data.redactionApplied = true;
|
|
666
|
+
}
|
|
667
|
+
// Load template metadata from .guardlink/cxg-templates/
|
|
668
|
+
const templatesDir = join(root, '.guardlink', CXG_TEMPLATES_DIR);
|
|
669
|
+
if (existsSync(templatesDir)) {
|
|
670
|
+
try {
|
|
671
|
+
const files = readdirSync(templatesDir).filter(f => f.endsWith('.py') || f.endsWith('.yaml') || f.endsWith('.yml') ||
|
|
672
|
+
f.endsWith('.go') || f.endsWith('.rs') || f.endsWith('.js') || f.endsWith('.sh'));
|
|
673
|
+
for (const file of files) {
|
|
674
|
+
try {
|
|
675
|
+
const raw = readFileSync(join(templatesDir, file), 'utf-8');
|
|
676
|
+
const ext = file.split('.').pop() || '';
|
|
677
|
+
// Anchor on complete field names: `id: "x"`, `"id": "x"`, `template_id = "x"`.
|
|
678
|
+
// The previous loose regex matched "id" inside words like `bridge`
|
|
679
|
+
// (captured "ge") and `guide` (captured "e"); the severity regex
|
|
680
|
+
// missed Python `severity = "critical"` because it required a colon.
|
|
681
|
+
const idMatch = raw.match(/["']?(?:template_)?id["']?\s*[:=]\s*["']([a-z0-9_-]+)["']/i);
|
|
682
|
+
const sevMatch = raw.match(/["']?severity["']?\s*[:=]\s*["']?(critical|high|medium|low|info)["']?/i);
|
|
683
|
+
const tagsMatch = raw.match(/tags[:\s]*\[([^\]]*)\]/);
|
|
684
|
+
data.templates.push({
|
|
685
|
+
filename: file,
|
|
686
|
+
id: idMatch?.[1] || file.replace(/\.[^.]+$/, ''),
|
|
687
|
+
severity: sevMatch?.[1] || 'medium',
|
|
688
|
+
language: ext === 'py' ? 'python' : ext === 'yml' || ext === 'yaml' ? 'yaml' : ext,
|
|
689
|
+
tags: tagsMatch?.[1]
|
|
690
|
+
? tagsMatch[1].split(',').map(t => t.trim().replace(/["']/g, '')).filter(Boolean)
|
|
691
|
+
: [],
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
catch { /* skip unreadable */ }
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
catch { /* dir not readable */ }
|
|
698
|
+
}
|
|
699
|
+
return data;
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Serialize pentest findings into a compact text summary for LLM context.
|
|
703
|
+
*/
|
|
704
|
+
export function serializePentestFindings(data) {
|
|
705
|
+
if (data.scans.length === 0 && data.templates.length === 0)
|
|
706
|
+
return '';
|
|
707
|
+
const lines = ['## Pentest Findings (CXG Scan Results)', ''];
|
|
708
|
+
if (data.templates.length > 0) {
|
|
709
|
+
lines.push(`### Templates (${data.templates.length})`);
|
|
710
|
+
for (const t of data.templates) {
|
|
711
|
+
lines.push(`- ${t.id} [${t.severity}] (${t.language}) — ${t.tags.slice(0, 5).join(', ')}`);
|
|
712
|
+
}
|
|
713
|
+
lines.push('');
|
|
714
|
+
}
|
|
715
|
+
if (data.scans.length > 0) {
|
|
716
|
+
lines.push(`### Scan Results (${data.totalFindings} findings across ${data.scans.length} scan(s))`);
|
|
717
|
+
const sevSummary = Object.entries(data.findingsBySeverity)
|
|
718
|
+
.sort(([, a], [, b]) => b - a)
|
|
719
|
+
.map(([sev, count]) => `${sev}: ${count}`)
|
|
720
|
+
.join(', ');
|
|
721
|
+
if (sevSummary)
|
|
722
|
+
lines.push(`Severity breakdown: ${sevSummary}`);
|
|
723
|
+
lines.push('');
|
|
724
|
+
for (const scan of data.scans) {
|
|
725
|
+
lines.push(`#### Scan ${scan.scan_id.slice(0, 8)} (${scan.completed_at?.slice(0, 19) || 'unknown'}) — ${scan.source_file}`);
|
|
726
|
+
lines.push(`Templates executed: ${scan.statistics?.templates_executed || '?'} | Success rate: ${((scan.statistics?.success_rate || 0) * 100).toFixed(0)}%`);
|
|
727
|
+
lines.push('');
|
|
728
|
+
for (const f of scan.findings) {
|
|
729
|
+
lines.push(`**[${f.severity.toUpperCase()}] ${f.title}** (${f.template_id})`);
|
|
730
|
+
lines.push(` CWE: ${f.cwe_ids.join(', ') || 'none'} | Confidence: ${formatConfidence(f.confidence)}`);
|
|
731
|
+
lines.push(` ${f.description}`);
|
|
732
|
+
if (f.evidence?.request)
|
|
733
|
+
lines.push(` Request: ${String(f.evidence.request).slice(0, 300)}`);
|
|
734
|
+
if (f.evidence?.response)
|
|
735
|
+
lines.push(` Response: ${String(f.evidence.response).slice(0, 300)}`);
|
|
736
|
+
if (f.evidence?.matched_patterns?.length)
|
|
737
|
+
lines.push(` Patterns: ${f.evidence.matched_patterns.join(', ')}`);
|
|
738
|
+
lines.push(` Remediation: ${f.remediation}`);
|
|
739
|
+
lines.push('');
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
return lines.join('\n');
|
|
744
|
+
}
|
|
582
745
|
//# sourceMappingURL=index.js.map
|