{"slug":"secret-handling-review","name":"Secret Handling Review","version":"1.0.0","updated_at":"2026-10-30T01:54:38.037Z","use_when":"Reviews pasted application code, scripts and config for the four ways a secret leaks from the code that uses it, and lists only those, one line each with a fixed code, the place, who can then read the secret and the fix - or exactly No findings. It catches a secret value written to a log or printed (the key itself, an object or environment dump that contains it), a secret placed in a URL query string, a secret typed into source or a committed file, and a server secret sent to the browser through a public environment prefix or a prop of a client component. It leaves out the safe look-alikes: printing only that a key is present, its length or its last four characters, a publishable key that is public by design, and a secret read from the environment on the server. Use to review code that calls an API with a key, to check a Next.js or Vite project before release, or to gate a pull request that touches credentials.","not_for":"Removing secrets from a text, CI workflow files, container build files, rotation and scanning tools, and the storage of a value that lies outside the paste. It reads pasted code and judges only what is written in it.","languages":["en"],"tags":["secrets","api-keys","logging","environment-variables","code-review","security"],"category":"code","category_url":"https://aiskills402.com/categories/code","keywords":["URL query string","public environment prefix","publishable key","client component"],"faq":[{"q":"Last four characters in a log: a leak or not?","a":"Not reported. Printing that a key is present, its length or its last four characters does not hand anyone the secret, so the skill leaves it out. It reports the key itself, an object that holds it, an environment dump, or an error that echoes the config."},{"q":"Why is a NEXT_PUBLIC_ value sometimes fine?","a":"The prefix publishes the value to every visitor by design, so it is wrong for a token and right for a value meant to be public, such as a payment provider's publishable key or a CAPTCHA site key. The skill judges what the value is used for, not only its name."},{"q":"Does it repeat a secret it finds?","a":"No. The answer names the variable and the place, never the value, so the review itself can be pasted into a ticket. A key read with process.env on the server is not reported, because reading from the environment is the safe way to do it."},{"q":"What stood in the three test snippets?","a":"A forecast script that printed its config and sent the key in a query string, a shop with a typed mail password and an admin token under the public prefix, and a clean reports route. Sonnet and Haiku answered each once; see the test summary for the hand-read verdicts."}],"examples":[{"lang":"en","model":"claude-sonnet-5-5","input_excerpt":"// scripts/forecast.mjs\nconst config = {\n  baseUrl: 'https://api.example.com/v1',\n  apiKey: process.env.WEATHER_API_KEY,\n  timeoutMs: 5000,\n};\n\nconsole.log('starting with config', config);\nconsole.log('key present:', Boolean(config.apiKey), 'length:', config.apiKey.length, 'ends with:', config.apiKey.slice(-4));\n\nexport async function getForecast(city) {…","output_excerpt":"SECRET-LOGGED — `console.log('starting with config', config)` — the config object holds `apiKey` (from `WEATHER_API_KEY`), so anyone who can read the log or console output reads the key — print only `baseUrl` and `timeoutMs`, or mask `apiKey`…"}],"page_url":"https://aiskills402.com/skills/secret-handling-review","markdown_url":"https://aiskills402.com/skills/secret-handling-review.md","image_url":"https://cdn.aiskills402.com/og/skills/secret-handling-review/0362c097.png","related_url":"https://api.aiskills402.com/v1/skills/secret-handling-review/related","purchases_count":null,"tested":{"date":"2026-10-29","strong":{"model":"claude-sonnet-5-5 (Claude Code alias \"sonnet\")","verdict":"Right on all 3 cases, read by hand. On the forecast script it named the config object printed at start-up and the key placed in the query string, and left out the line that prints only that the key is present, its length and its last four characters, and the key read from the environment. On the shop it found the mail password typed into a committed file and the admin token under the public prefix in a client component, and left out the publishable payment key and the CAPTCHA site key under the same prefix. On the clean reports route it answered exactly No findings."},"weak":{"model":"claude-haiku-5-5 (Claude Code alias \"haiku\")","verdict":"Right on all 3 cases, read by hand. It gave the same pairs of findings as Sonnet on the forecast script and on the shop, with the same safe look-alikes left out, and answered exactly No findings on the clean route. Two of its lines ended with a full stop and one answer was indented by four spaces, which the checks accept."},"note":"Light test: three cases (two planted, one clean), one run per model; no comparison without the skill. The code was written by us with made-up values only; each planted case carries a safe look-alike (a presence, length and last-four print, a publishable key and a site key under the public prefix), and neither planted case has a comment pointing at the defect. A fifth code the brief suggested, a secret passed as a command-line argument, was dropped because no official page read on 29 October 2026 supports it. Facts come from OWASP cheat sheets and the Next.js, Vite and Stripe documentation, read on 29 October 2026; there are no owner-measured facts.","report_url":null},"price_usd":"0.01","price_micro":10000,"size_bytes":8024,"sha256":"7adc71c9a6289af4f5d3b4cdfac777bacf30ce2d5c94b354bd8525c20c20e56b","outline":["The answer","What is a secret","The codes","How to read the code","Rules","Work in this order","Short example"],"license":{"summary":"Perpetual, non-exclusive; use and modify for yourself incl. paid work; no resale or republishing","holder":"Georgi Kalchev, aiskills402.com","url":"https://aiskills402.com/docs#license"},"buy_url":"https://api.aiskills402.com/v1/skills/secret-handling-review/file","redownload_url_template":"https://api.aiskills402.com/v1/purchases/{token}","mcp_tool":null,"payment":{"protocol":"x402","scheme":"exact","asset":"USDC","selling":true,"network":"base","network_caip2":"eip155:8453","pay_to":"0xbc0dcc70d8b5d85541d86ffc68d988fd59c22e68","facilitator":"cdp"},"seo_title":"Secret Handling Review for Code","seo_description":"Finds secrets in logs, URLs, committed source and browser bundles, while skipping publishable keys and site keys. Pay $0.01 once, in USDC.","versions":[{"version":"1.0.0","date":"2026-10-30","changelog":"# Changelog\n\n## 1.0.0 — 2026-10-29\n\nFirst release, written in the light-test batch of 29 October 2026 (three cases, price $0.01). The idea is ours; no foreign skill was opened, facts come from OWASP cheat sheets and the Next.js, Vite and Stripe documentation (see notes/ideas.md). Output: one line per finding with a fixed code, or exactly `No findings.`\n\nTest: three cases written by hand (two planted, each with a safe look-alike, one clean control), one run on Claude Sonnet and one on Claude Haiku, no run without the skill, no iteration on the skill text after the runs. `test/control.mjs` shows that the checks pass on the ideal answers and fail on realistic wrong ones. See `test-summary.json` for the verdicts read by hand.\n"}]}