Fix the staged secret scan for config files

Review the AI's codeMedium15 min

Your task

You asked an AI agent to set up your app to call the payments API. It worked, and the agent had pasted the live secret key into a TypeScript constant and a docker-compose.yml. Before anyone pushes, your team now scans the added lines of the staged diff.

An assistant wrote scan_staged_secrets(paths, lines). It is in the editor. It has a bug. Find it and fix it.

Input and output:

  • paths, lines: the added lines of the staged diff. lines[i] was added to the file paths[i]. If one list is longer, ignore its extra items.
  • Return findings written "<path>: <reason>", each one once, in the order first found.

Rules the tests check. For each line, use the first rule that applies:

  1. The file's base name, the part after the last /, starts with .env. If it starts with .env.example or .env.sample, it is a template, and the line has no finding at all. Otherwise the reason is "env file staged".
  2. "hardcoded secret": the line assigns a credential a literal value. All of these must hold:
    • The separator is the first = or : in the line, whichever comes first. A line with neither is not a hardcoded secret.
    • The name, the text before the separator, uppercased, contains KEY, SECRET, TOKEN or PASSWORD.
    • The value, the text after the separator trimmed of whitespace, is not empty, does not contain ENV in any case, and contains neither ${ nor (. Those mean the value is read at runtime, not written in.
  3. "server secret in client code": the file is client code, and the line contains process.env. but not NEXT_PUBLIC_. Client code is a path that ends with .jsx or .tsx, contains components/ or /client/, or starts with client/.

Examples

scan_staged_secrets(paths: list[str], lines: list[str]) -> list[str]
Example 1
Inputscan_staged_secrets(["src/config/payments.ts", "src/config/payments.ts"], ["const PAYMENTS_API_KEY = \"sk_live_4eC39HqLyjWDarjt\";", "export const BASE_URL = \"https://api.pay.example\";"])
Output["src/config/payments.ts: hardcoded secret"]
Example 2
Inputscan_staged_secrets([".env.local", "app/api/pay/route.ts"], ["STRIPE_SECRET_KEY=sk_live_51HxyzABC", "const key = process.env.STRIPE_SECRET_KEY;"])
Output[".env.local: env file staged"]
Example 3
Inputscan_staged_secrets(["components/Dashboard.tsx"], ["const key = process.env.STRIPE_SECRET_KEY;"])
Output["components/Dashboard.tsx: server secret in client code"]