/** * Pass #90: scan-secrets (category: security, CWE-798) * * Detects hardcoded credentials across all 7 supported languages * (Java, JS/TS, Python, Go, Rust, Bash, HTML). * * Two detection layers: * * 1. Provider-specific regex patterns. ~16 high-confidence prefixes / * shapes (AWS AKIA, GitHub `ghp_`/`gho_`/`ghs_`/`ghu_`/`ghr_`, * Stripe `sk_live_`/`pk_live_`, OpenAI `sk-`, Anthropic `sk-ant-`, * Slack `xox[baprs]-`, Google `AIza`, JWT `eyJ..eyJ..`, PEM private * keys, npm `npm_`). Each match emits a finding with * `rule_id: 'hardcoded-credential'` (matches the legacy Bash * detection in LanguageSourcesPass). * * 2. Shannon-entropy scan of inline string literals. For each * base64-shaped or hex-shaped quoted string above the length gate, * compute Shannon entropy; flag if it crosses the per-shape * threshold. Heavily denylisted (UUIDs, bare SHA hashes, common * placeholders like "changeme" / "your-key-here", env-var refs) * and gated against test-file paths. Emits * `rule_id: 'hardcoded-credential-entropy'` (distinct rule so users * can filter the noisier entropy branch without losing provider * coverage). * * Both layers dedupe against any prior `hardcoded-credential` / * `hardcoded-credential-entropy` findings already in the pipeline's * findings buffer, so the pre-existing Bash detection * (`findBashPatternFindings` in language-sources-pass.ts) is never * double-reported. * * Test files (path-based heuristic) are skipped entirely. * * Detection is regex-based on the raw source text, so the pass works * on every language without per-grammar tree walking. This is the same * approach used by `language-sources-pass.findBashPatternFindings` and * `todo-in-prod-pass`. */ import type { AnalysisPass, PassContext } from '../../graph/analysis-pass.js'; export interface ScanSecretsPassResult { /** Number of findings emitted in each layer (for debugging / tests). */ providerFindings: number; entropyFindings: number; } export declare class ScanSecretsPass implements AnalysisPass { readonly name = "scan-secrets"; readonly category: "security"; run(ctx: PassContext): ScanSecretsPassResult; /** Length + shape + denylist filter before entropy is computed. */ private isCandidate; /** * Shannon-entropy gate (#125 Gate 4 — REQUIRED field-name match). * * The entropy layer emits ONLY when the enclosing assignment LHS * identifier matches a credential keyword (password / secret / token / * api_key / etc.). Without this requirement, the layer flagged every * high-entropy string — attribution keys, base64 resource blobs, public * encoding alphabets — as credentials. Provider patterns (Layer 1) and * named-credential matcher (Layer 1b) remain the recall safety net for * credentials that don't fit the `FIELD = "..."` shape. * * Base64-shaped strings need higher entropy than hex-shaped (hex alphabet * is 4 bits/char by construction). */ private passesEntropyGate; } //# sourceMappingURL=scan-secrets-pass.d.ts.map