ワンクリックで
secrets-handling
处理密钥/凭据/token 时使用。防止泄露进代码、日志、前端。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
处理密钥/凭据/token 时使用。防止泄露进代码、日志、前端。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
做 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(无真实值)。