with one click
secrets-handling
处理密钥/凭据/token 时使用。防止泄露进代码、日志、前端。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
处理密钥/凭据/token 时使用。防止泄露进代码、日志、前端。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
做 Cocos Creator 多机型/多分辨率适配时使用。Canvas、Widget、安全区。
Cocos Creator 用 AssetBundle 做分包/远程资源时使用。加载、释放、依赖、缓存。
优化 Cocos Creator 渲染性能时使用。合批、图集、动静分离、Label。
给 Cocos Creator 原生包做热更新时使用。version manifest、增量、校验、回滚。
写 Cocos Creator 动效/动画时使用。tween、Animation、Spine、性能与清理。
做 Cocos Creator 大量条目列表时使用。虚拟列表、节点复用。
| name | secrets-handling |
| description | 处理密钥/凭据/token 时使用。防止泄露进代码、日志、前端。 |
| category | security |
| tags | ["密钥","secret","凭据"] |
规则: 任何密钥、token、密码都不允许出现在代码文件、配置文件、注释里;通过环境变量或专用 secret 管理工具(AWS Secrets Manager、HashiCorp Vault、GCP Secret Manager)在运行时注入;.env 文件本地使用但必须加入 .gitignore。
为什么: AI 生成示例代码时最常见的陷阱就是把真实密钥硬编码进代码并提交。GitHub 的安全研究表明,每天有数万个 API key 被意外推送到公开仓库,其中大量来自"我只是先写死方便测试,待会改"的侥幸心态,但改了代码、历史记录里的密钥仍然存在。GitGuardian 报告显示 AI 生成的代码中密钥硬编码比例显著高于人类开发者。
怎么做:
# 反例:硬编码
OPENAI_API_KEY = "sk-proj-abc123xyz..." # ❌ 直接写死在代码里
# 正例:从环境变量读取
import os
OPENAI_API_KEY = os.environ["OPENAI_API_KEY"] # ✅ 启动时不存在则报错
# .gitignore
.env
.env.local
.env.production
*.pem
*_rsa
*_rsa.pub
credentials.json
.env.example(只含变量名,无值)作为文档,不提供含真实值的 .env。规则: 发现密钥被提交进 git 后,第一步是立即在对应服务撤销/轮换该密钥,而不是先删除提交或 rebase;历史记录里的密钥通过 git filter-repo 清除只是事后补救,不能替代密钥轮换。
为什么: AI 有时建议"删掉那次提交然后 force push 就好了",这是错误的响应姿势。在发现密钥泄露到 force push 完成之间的时间窗口内,密钥仍然有效;更重要的是,GitHub 等平台会镜像 push 事件,第三方爬虫可能在秒级内就已经抓取并存档了该密钥。2022 年 Samsung 源码泄露事件中,即便代码被删除,密钥早已被利用。
怎么做:
密钥泄露响应流程:
1. [立即] 在服务控制台撤销/轮换该密钥(AWS IAM、GitHub Settings、Stripe Dashboard 等)
2. [立即] 审计该密钥从泄露到轮换期间的访问日志,确认是否被滥用
3. [之后] 用 git filter-repo 清理历史(需要团队所有人重新 clone)
4. [之后] 复盘:补充 pre-commit 扫描防止再次发生
规则: 日志输出、异常信息、HTTP 响应、前端 JavaScript(包括注释和 source map)都不能包含密钥或完整 token;脱敏展示时只显示前4后4位,中间用 **** 替代。
为什么: AI 生成的调试日志和错误处理代码里频繁出现 logger.error(f"API调用失败,key={api_key}, error={e}"),这行日志把完整 API key 写进日志文件。日志文件通常被运维、开发、监控系统等多人访问,远比代码库传播面广。前端 bundle 里的密钥更危险,任何访问网页的用户打开开发者工具即可获取。
怎么做:
def mask_secret(secret: str) -> str:
"""只保留前4后4位,其余脱敏"""
if not secret or len(secret) <= 8:
return "****"
return f"{secret[:4]}****{secret[-4:]}"
# 反例
logger.error(f"调用失败: key={api_key}") # ❌ 完整 key 进日志
# 正例
logger.error(f"调用失败: key={mask_secret(api_key)}, error={type(e).__name__}") # ✅
clientId(受域名限制),不能有任何后端密钥。.env 内容打包进 webpack bundle(检查 DefinePlugin 的使用)。规则: 每个密钥只授予完成其任务所需的最小权限;API key 和 service account 设置过期时间;开发/测试/生产使用完全独立的密钥集,不共用。
为什么: AI 生成示例代码时总是用 admin 权限的 key(因为权限不足不会报错),然后这个 key 就被沿用到生产。一旦该 key 泄露,攻击者获得全局管理员权限。同样,AI 生成的脚本里经常看到开发环境的 test_key_xxx 被提交进 docker-compose.prod.yml——因为"先用开发的测一下",后来忘了换。
怎么做:
权限设计示例(AWS S3):
- 生产应用 IAM 角色:s3:GetObject, s3:PutObject(只操作指定 bucket)
- 开发账号:s3:ListBucket, s3:GetObject(只读,不能写)
- CI/CD:s3:PutObject(只能上传,不能删除)
- 不创建 "AllAccess" 策略的 IAM user
dev_user/dev_password vs prod_service_user(不同账号,不同权限)。规则: 在 git pre-commit hook 或 CI 中集成密钥扫描工具(git-secrets、gitleaks、detect-secrets);扫描失败时阻止提交,不仅仅是告警。
为什么: 密钥泄露 90% 以上是无意为之——AI 生成的代码包含占位符格式的真实 key,开发者没有意识到。人工 code review 很难每次都发现,尤其在大 PR 里。自动化扫描是最后一道低成本高效率的防线。Yelp 的 detect-secrets 研究表明,在大型工程组织里,自动化扫描能拦截约 85% 的意外密钥提交。
怎么做:
# 安装 gitleaks pre-commit hook
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
hooks:
- id: gitleaks
args: ["--no-git"] # 扫描暂存区,不扫历史
# 本地安装
pip install pre-commit
pre-commit install
# CI 全量历史扫描
- name: Scan secrets
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ghp_、sk-)加入扫描规则。# 反例
import boto3
# ❌ 密钥硬编码在代码里
AWS_KEY = "AKIAIOSFODNN7EXAMPLE"
AWS_SECRET = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
def upload_file(filename):
s3 = boto3.client(
"s3",
aws_access_key_id=AWS_KEY, # ❌ admin 权限 key
aws_secret_access_key=AWS_SECRET
)
try:
s3.upload_file(filename, "my-bucket", filename)
except Exception as e:
# ❌ 完整 key 和 secret 进日志
print(f"上传失败: key={AWS_KEY}, secret={AWS_SECRET}, err={e}")
# 正例
import os
import boto3
import logging
logger = logging.getLogger(__name__)
def mask_secret(s: str) -> str:
return f"{s[:4]}****{s[-4:]}" if len(s) > 8 else "****"
def upload_file(filename: str, bucket: str) -> None:
# ✅ 从环境变量读取,启动时不存在则立即报错
aws_key = os.environ["AWS_ACCESS_KEY_ID"]
aws_secret = os.environ["AWS_SECRET_ACCESS_KEY"]
# ✅ 最好用 IAM role(不需要显式凭据),退而求其次才用 env var key
s3 = boto3.client(
"s3",
aws_access_key_id=aws_key,
aws_secret_access_key=aws_secret,
region_name=os.environ.get("AWS_REGION", "ap-east-1"),
)
try:
s3.upload_file(filename, bucket, filename)
logger.info("上传成功: %s -> %s", filename, bucket)
except Exception as e:
# ✅ 日志里只显示 key 的脱敏形式
logger.error("上传失败: key=%s, bucket=%s, error=%s",
mask_secret(aws_key), bucket, type(e).__name__)
raise
.env 文件已加入 .gitignore,仓库中只有 .env.example(无真实值)。