fullcourtdefense-cli 1.14.2 → 1.14.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.
@@ -124,6 +124,12 @@ function scoreFromFindings(findings) {
124
124
  return Math.max(0, Math.min(100, score));
125
125
  }
126
126
  function scanTextLines(filePath, content, category, out, seen) {
127
+ // Placeholder/template files (.env.example, *.sample, *.template) hold intentional
128
+ // dummy values — report as info so real findings aren't drowned out (Gitleaks
129
+ // ignores these entirely; we keep them visible but non-alarming).
130
+ const isExampleFile = /\.(example|sample|template|dist)(\.|$)/i.test(path.basename(filePath));
131
+ // Vars with client-bundle prefixes ship to the browser by design.
132
+ const clientExposedPrefix = /^\s*(?:VITE_|NEXT_PUBLIC_|REACT_APP_|EXPO_PUBLIC_|NUXT_PUBLIC_)/;
127
133
  const lines = content.split(/\r?\n/);
128
134
  for (let i = 0; i < lines.length; i++) {
129
135
  const line = lines[i];
@@ -144,22 +150,41 @@ function scanTextLines(filePath, content, category, out, seen) {
144
150
  if (seen.has(id))
145
151
  continue;
146
152
  seen.add(id);
153
+ // Firebase/Google web API keys behind a client-bundle prefix are public by
154
+ // design — the risk is a missing restriction, not the exposure itself.
155
+ const isClientExposedWebKey = pattern.provider === 'google' && clientExposedPrefix.test(line);
156
+ let severity = pattern.severity;
157
+ let title = pattern.title;
158
+ let detail = pattern.impact
159
+ ? `Matched ${pattern.provider} pattern in ${path.basename(filePath)}. If leaked: ${pattern.impact}.`
160
+ : `Matched ${pattern.provider} pattern in ${path.basename(filePath)}`;
161
+ let remediation = pattern.provider === 'private_key'
162
+ ? 'Move keys to a secure store; never commit private keys. Use ssh-agent or encrypted keys.'
163
+ : PROVIDER_REMEDIATION[pattern.provider]
164
+ || 'Rotate this credential immediately and store it in a secret manager or OS keychain — not in plain files.';
165
+ if (isExampleFile) {
166
+ severity = 'info';
167
+ title = `${pattern.title} (example/template file)`;
168
+ detail = `Matched ${pattern.provider} pattern in ${path.basename(filePath)} — looks like an intentional placeholder.`;
169
+ 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
+ }
171
+ else if (isClientExposedWebKey) {
172
+ severity = 'medium';
173
+ title = 'Google/Firebase web API key (client-exposed)';
174
+ detail = `Matched google pattern in ${path.basename(filePath)} on a client-bundle variable — this key ships to the browser by design.`;
175
+ remediation = 'Not a secret in the classic sense, but add HTTP-referrer/API restrictions in Google Cloud console → Credentials so it only works from your domains.';
176
+ }
147
177
  out.push({
148
178
  id,
149
179
  category,
150
- severity: pattern.severity,
180
+ severity,
151
181
  provider: pattern.provider,
152
182
  filePath,
153
183
  lineNumber: i + 1,
154
- title: pattern.title,
155
- detail: pattern.impact
156
- ? `Matched ${pattern.provider} pattern in ${path.basename(filePath)}. If leaked: ${pattern.impact}.`
157
- : `Matched ${pattern.provider} pattern in ${path.basename(filePath)}`,
184
+ title,
185
+ detail,
158
186
  redactedPreview: redact(raw),
159
- remediation: pattern.provider === 'private_key'
160
- ? 'Move keys to a secure store; never commit private keys. Use ssh-agent or encrypted keys.'
161
- : PROVIDER_REMEDIATION[pattern.provider]
162
- || 'Rotate this credential immediately and store it in a secret manager or OS keychain — not in plain files.',
187
+ remediation,
163
188
  });
164
189
  if (out.length >= MAX_FINDINGS)
165
190
  return;
package/dist/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "1.14.2"
2
+ "version": "1.14.3"
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fullcourtdefense-cli",
3
- "version": "1.14.2",
3
+ "version": "1.14.3",
4
4
  "description": "Full Court Defense CLI — security scanning for AI agents from your terminal",
5
5
  "main": "dist/index.js",
6
6
  "bin": {