Fix the browser exposure scan for hardcoded keys
Your task
An AI generated a Next.js dashboard component with const API_KEY = "sk_live_...". Code that runs in the browser ships in the JavaScript bundle, so that key goes to every visitor, who can read it in the browser's developer tools. Your team now scans each module for hardcoded secrets and marks the ones the browser can see.
An assistant wrote scan_client_secret_exposure(lines). It is in the editor. It has a bug. Find it and fix it.
Input and output:
lines: the module's source lines.- Return findings written
"<line number>:<where>:<prefix>", in line order, at most one per line. Line numbers start at 1, and<where>isbrowserorserver.
Rules the tests check:
- A comment line, one that starts with
//after trimming whitespace, is ignored by every rule. - The module runs in the browser when any line that is not a comment contains
use client,useEffect,useState,window.ordocument.. Then every finding saysbrowser. Otherwise every finding saysserver. - Skip a line that contains
process.env: it reads the secret from the environment. - Check every other line for these prefixes, in this order:
sk_live_,sk_test_,ghp_,AKIA. Report the first one in that order that appears anywhere in the line. Matching is case sensitive. - A publishable key such as
pk_live_is meant to be public and is not reported.
Examples
scan_client_secret_exposure(lines: list[str]) -> list[str]Example 1
Input
scan_client_secret_exposure(["export default function Dashboard() {", " const API_KEY = \"sk_live_4eC39HqLyjWDarjtT1zdp7dc\";", " useEffect(() => {", " fetch(`https://api.metrics.io/v1/data?key=${API_KEY}`).then(r => r.json());", " }, []);", "}"])Output
["2:browser:sk_live_"]Example 2
Input
scan_client_secret_exposure(["const stripe = require('stripe');", "const key = \"sk_live_9zQ2mNbVcXs1\";", "module.exports = stripe(key);"])Output
["2:server:sk_live_"]Example 3
Input
scan_client_secret_exposure(["\"use client\";", "const PUBLISHABLE = \"pk_live_51H8xVisibleOnPurpose\";", "const token = process.env.NEXT_PUBLIC_TOKEN;"])Output
[]