fullcourtdefense-cli 1.14.3 → 1.14.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.
|
@@ -60,6 +60,8 @@ export interface DesktopDiscoveryHost {
|
|
|
60
60
|
probeMode: 'config' | 'deep';
|
|
61
61
|
/** Windows-only: PowerShell audit coverage (ScriptBlock Logging + Transcription). */
|
|
62
62
|
shellAudit?: ShellAuditReport;
|
|
63
|
+
/** True when the scan ran on an ephemeral CI runner (GitHub Actions, GitLab, etc.) — not a user machine. */
|
|
64
|
+
isCi?: boolean;
|
|
63
65
|
}
|
|
64
66
|
export declare function discoverCommand(args: DiscoverArgs, config: BotGuardConfig): Promise<void>;
|
|
65
67
|
/** Upload-only discover — used after install-mcp-gateway --upload. */
|
|
@@ -93,6 +93,16 @@ function machineFingerprint() {
|
|
|
93
93
|
const seed = [os.hostname(), os.userInfo().username, os.platform(), os.arch()].join('|');
|
|
94
94
|
return crypto.createHash('sha256').update(seed).digest('hex').slice(0, 16);
|
|
95
95
|
}
|
|
96
|
+
/** Detect ephemeral CI runners so they are never listed as user machines in the fleet. */
|
|
97
|
+
function isCiEnvironment() {
|
|
98
|
+
return process.env.GITHUB_ACTIONS === 'true'
|
|
99
|
+
|| process.env.GITLAB_CI === 'true'
|
|
100
|
+
|| process.env.TF_BUILD === 'True' // Azure Pipelines
|
|
101
|
+
|| !!process.env.JENKINS_URL
|
|
102
|
+
|| !!process.env.BUILDKITE
|
|
103
|
+
|| !!process.env.CIRCLECI
|
|
104
|
+
|| process.env.CI === 'true';
|
|
105
|
+
}
|
|
96
106
|
function buildHostMetadata(userEmail, probeMode = 'config') {
|
|
97
107
|
const info = os.userInfo();
|
|
98
108
|
return {
|
|
@@ -103,6 +113,7 @@ function buildHostMetadata(userEmail, probeMode = 'config') {
|
|
|
103
113
|
scannedAt: new Date().toISOString(),
|
|
104
114
|
probeMode,
|
|
105
115
|
shellAudit: (0, windowsAudit_1.getShellAuditReport)(),
|
|
116
|
+
isCi: isCiEnvironment() || undefined,
|
|
106
117
|
};
|
|
107
118
|
}
|
|
108
119
|
/** Where MCP client configs live — see discoverPaths.ts for the canonical list. */
|
|
@@ -100,6 +100,8 @@ const SKIP_DIR_NAMES = new Set([
|
|
|
100
100
|
const MAX_FILE_BYTES = 256 * 1024;
|
|
101
101
|
const MAX_ENV_FILES = 400;
|
|
102
102
|
const MAX_FINDINGS = 200;
|
|
103
|
+
const INLINE_ALLOW_COMMENT = /\b(?:gitleaks:allow|trufflehog:ignore|pragma:\s*allowlist\s+secret|nosecret|secretlint-disable)\b/i;
|
|
104
|
+
const PLACEHOLDER_WORDS = /(?:example|sample|dummy|fake|placeholder|changeme|change_me|replace_me|your[_-]?key|your[_-]?token|test[_-]?only)/i;
|
|
103
105
|
function redact(value) {
|
|
104
106
|
const trimmed = value.trim();
|
|
105
107
|
if (trimmed.length <= 8)
|
|
@@ -109,6 +111,21 @@ function redact(value) {
|
|
|
109
111
|
function findingId(parts) {
|
|
110
112
|
return crypto.createHash('sha256').update(parts.join('|')).digest('hex').slice(0, 16);
|
|
111
113
|
}
|
|
114
|
+
function looksLikePlaceholder(raw, line) {
|
|
115
|
+
const joined = `${raw} ${line}`;
|
|
116
|
+
if (PLACEHOLDER_WORDS.test(joined))
|
|
117
|
+
return true;
|
|
118
|
+
if (/(?:sk-proj-|sk-|gsk_|xai-|hf_|npm_|ag_org_|shsk_)[x0a]{16,}/i.test(raw))
|
|
119
|
+
return true;
|
|
120
|
+
const compact = raw.replace(/[^A-Za-z0-9]/g, '');
|
|
121
|
+
if (!compact)
|
|
122
|
+
return false;
|
|
123
|
+
if (/^(?:x+|0+|1+|a+|z+)$/i.test(compact))
|
|
124
|
+
return true;
|
|
125
|
+
if (/^(?:1234567890|abcdef|abc123){2,}$/i.test(compact))
|
|
126
|
+
return true;
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
112
129
|
function scoreFromFindings(findings) {
|
|
113
130
|
let score = 100;
|
|
114
131
|
for (const f of findings) {
|
|
@@ -135,6 +152,8 @@ function scanTextLines(filePath, content, category, out, seen) {
|
|
|
135
152
|
const line = lines[i];
|
|
136
153
|
if (!line.trim() || line.trim().startsWith('#'))
|
|
137
154
|
continue;
|
|
155
|
+
if (INLINE_ALLOW_COMMENT.test(line))
|
|
156
|
+
continue;
|
|
138
157
|
// First (most specific) pattern wins per matched string — prevents e.g. an
|
|
139
158
|
// sk-ant- Anthropic key from also being reported as a generic OpenAI sk- key.
|
|
140
159
|
const matchedRaws = [];
|
|
@@ -168,6 +187,12 @@ function scanTextLines(filePath, content, category, out, seen) {
|
|
|
168
187
|
detail = `Matched ${pattern.provider} pattern in ${path.basename(filePath)} — looks like an intentional placeholder.`;
|
|
169
188
|
remediation = 'Confirm this is a dummy value. If a real credential was pasted into the example file, rotate it and replace with a placeholder.';
|
|
170
189
|
}
|
|
190
|
+
else if (looksLikePlaceholder(raw, line)) {
|
|
191
|
+
severity = 'info';
|
|
192
|
+
title = `${pattern.title} (placeholder-like value)`;
|
|
193
|
+
detail = `Matched ${pattern.provider} pattern in ${path.basename(filePath)}, but the value/line contains common placeholder markers.`;
|
|
194
|
+
remediation = 'Replace placeholders before production. If this is a real credential despite the placeholder wording, rotate it and move it to a secret manager.';
|
|
195
|
+
}
|
|
171
196
|
else if (isClientExposedWebKey) {
|
|
172
197
|
severity = 'medium';
|
|
173
198
|
title = 'Google/Firebase web API key (client-exposed)';
|
package/dist/version.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fullcourtdefense-cli",
|
|
3
|
-
"version": "1.14.
|
|
3
|
+
"version": "1.14.4",
|
|
4
4
|
"description": "Full Court Defense CLI — security scanning for AI agents from your terminal",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"test:shell-guard": "npm run build && node scripts/test-shell-guard.js",
|
|
21
21
|
"test:cmd-guard": "npm run build && node scripts/test-cmd-guard.js",
|
|
22
22
|
"test:posix-guard": "npm run build && node scripts/test-posix-guard.js",
|
|
23
|
+
"test:secret-posture": "npm run build && node scripts/test-secret-posture-fixtures.js",
|
|
23
24
|
"test:ping-e2e": "npm run build && node scripts/test-ping-e2e.js",
|
|
24
25
|
"prepublishOnly": "npm run build"
|
|
25
26
|
},
|