Your AI Assistant Is Writing Secrets Into Source Code, and You're Letting It
作者:Seaworthy · 2026年10月22日
I keep seeing the same pattern in code reviews, and it makes me wince every time. A developer fires up their AI assistant, asks for a quick integration with a payment API, and gets back a tidy snippet with the secret key right there in the source file. They copy it in, it works, they move on. No environment variable, no .env file, no thought about what happens when that code hits a shared repository.
This is not a hypothetical. It is a routine outcome of the way AI assistants are trained and prompted. The models produce examples that are self-contained and runnable, which means they inline the credentials. The human on the other end, often someone who has never had to think about secrets management because their previous projects were small or internal, accepts the snippet as-is. The assistant is not doing anything malicious. It is doing exactly what it was asked: generate working code. The security basics are the developer's job, and they are getting skipped.
Here is the pattern I see most often. Someone asks for a client for a third-party service, and the response includes something like this:
# app.py
import requests
API_KEY = "sk_live_4eC39HqLyjWDarjtT1zdp7dc"
def charge_customer(amount):
return requests.post(
"https://api.payments.example/charge",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"amount": amount},
)
That key is now in the file. It is in the git history. It is in the backup of the repo. It is in the CI logs if the test suite prints the module. It is in the laptop of anyone who cloned the repo. And if the assistant gets used again to refactor that file, the key may get copied into a new location, or summarized into a comment, or included in a pasted error message that goes back to the model provider.
The fix is not complicated. It is the same thing we have been telling people for years: keep secrets out of source, load them from the environment, and make the absence of a secret a loud failure rather than a silent fallback. Here is the same module done correctly:
# app.py
import os
import requests
API_KEY = os.environ["PAYMENTS_API_KEY"]
def charge_customer(amount):
return requests.post(
"https://api.payments.example/charge",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"amount": amount},
)
Using os.environ["PAYMENTS_API_KEY"] instead of os.environ.get(...) matters. The bracket form raises KeyError at import time if the variable is missing, which is what you want. A default value or a silent None turns a configuration mistake into a runtime bug that shows up later, in production, at the worst possible moment. Fail early and fail loudly.
The part that actually takes discipline is the workflow around the assistant. When you prompt for a snippet that touches a credential, say so. Ask for the secret to be read from an environment variable. If the assistant ignores that and inlines a value anyway, edit it before you commit. If you are using an assistant that can see your open files, keep your .env file closed or excluded from context. Do not paste real keys into chat to ask "why is this failing?" Redact first.
I also want to push back on the idea that this is a junior developer problem. I have seen senior engineers accept inlined secrets from an assistant because the snippet was long and the key was buried in a config dictionary three levels deep. The assistant made it look intentional. That is the trap. The output is formatted confidently, so it reads as correct. Security review has to be a deliberate step, not an assumption that the assistant got it right.
A few concrete habits that help. Add a pre-commit hook that scans for high-entropy strings and known key prefixes, so an inlined secret fails before it reaches the remote. Keep a .env.example with placeholder names, and make sure .env is in .gitignore from the first commit. Rotate any key that has ever been committed, even if you think the repo is private. Private repos are not a security boundary, they are a permissions setting.
The broader point is that AI assistants are excellent at producing code that runs and poor at producing code that respects your operational context. Secrets management is operational context. The model does not know your deployment environment, your rotation policy, or who has read access to your repository. You do. That knowledge has to show up in the review, not just in the prompt.
If you want a starting point for catching these patterns before they land, Seaworthy's secret scanning covers common provider key formats and high-entropy strings in commits and pull requests.
本文由 AI 生成,总结了公开可用的来源。
Seaworthy 会扫描你的代码仓库,发现类似本文提到的各种问题。
安全漏洞、泄露的密钥和配置错误——在部署前捕获。免费运行,无需账户。