跳转到正文
报告库
用途分类 / 其他用途

Wizard Skill 安全审计

作者说它能做什么(原文)

Generate an interactive bash wizard that walks a human through steps only they can perform. Use when provisioning infrastructure, setting up credentials or CI secrets, walking an unfamiliar third-party dashboard, or running a one-off migration or cutover. Don't invoke this for steps the agent can perform itself.

第三方安全检查结论

先别安装或运行

已检查文件
3
发现的风险
4
会不会运行危险命令?检查是否下载程序后直接运行、让他人远程控制电脑,或藏起要运行的命令。未发现风险
会不会泄露文件和密钥?检查是否发送含密码或密钥的文件,以及代码里是否直接写了密钥。发现 3 项风险
高风险

GitHub 秘密写入依赖当前目录的隐式仓库上下文

原文依据:2 处
发现了什么

`set_secret` 调用 `gh secret set` 时没有指定仓库,也没有在上传前显示或确认 GitHub 账户和仓库。命令因此使用 `gh` 从当前环境推断出的目标。

为什么需要注意

若向导从错误的项目目录运行、仓库远程配置错误,或 `gh` 登录的是非预期账户,敏感凭据可能被写入另一个仓库,使该仓库的管理员或工作流能够使用它。

在 gh 已安装且已认证时,函数直接执行 `gh secret set`,没有 `--repo` 等显式目标,也没有在函数内显示或确认账户、仓库。实际目标因此取决于运行时的 gh/当前目录上下文;若用户从错误仓库目录运行,秘密可能被写入非预期仓库。用户可要求脚本在写入前显示并确认 `gh repo view` 得到的目标,或明确传入仓库。

template.sh:141来自代码打开原文件
# set_secret NAME VALUE sets a GitHub Actions repo secret via gh. Falls back# to a warning (and records it) if gh is unavailable or unauthenticated.set_secret() {  local name="$1" value="$2"  if command -v gh >/dev/null 2>&1 && gh auth status >/dev/null 2>&1; then    if printf '%s' "$value" | gh secret set "$name" >/dev/null 2>&1; then      WRITTEN_SECRET+=("$name")      printf '  %s✓ set%s GitHub secret %s\n' "$GREEN" "$RESET" "$name"      return
查看另外 1 个位置
template.sh:199来自代码打开原文件
ask_secret STRIPE_SECRET_KEY "Paste the secret key:"write_env STRIPE_PUBLISHABLE_KEY "$STRIPE_PUBLISHABLE_KEY"write_env STRIPE_SECRET_KEY "$STRIPE_SECRET_KEY"set_secret STRIPE_SECRET_KEY "$STRIPE_SECRET_KEY"   # CI needs this one# ──────────────────────────────────────────────────────────────────────────
中风险

示例模板是可执行的 Stripe 凭据收集流程,并非惰性示例

原文依据:2 处
发现了什么

尽管注释要求替换示例,文件底部仍包含会实际执行的 Shell 语句:打开 Stripe 页面、要求粘贴发布密钥和秘密密钥、写入 `.env`,并尝试设置 GitHub 仓库秘密。

为什么需要注意

如果用户误把 `template.sh` 当作仅供查看的模板并直接运行,在输入凭据后,本地环境文件会被修改,Stripe 秘密密钥还可能被发送到当前 GitHub 仓库。

模板将该段标为应替换的示例,但它仍是脚本的活动顶层代码。若用户在生成器替换此段之前直接运行 template.sh,它会打开 Stripe 页面、收集密钥、把两者写入当前目录的 .env,并尝试把秘密密钥写入当前 GitHub 仓库。用户可要求作者让模板默认不可执行,或在运行前确认示例已被替换及目标仓库正确。

template.sh:187来自代码打开原文件
TOTAL_STAGES=1banner "Stripe setup"# ── Example stage: replace with your real steps ───────────────────────────stage "Stripe: API keys"say "We'll grab your Stripe test keys and store them for local dev + CI."open_url "https://dashboard.stripe.com/test/apikeys"step "On the API keys page, copy the Publishable key (starts pk_test_)."ask STRIPE_PUBLISHABLE_KEY "Paste the publishable key:"step "Click 'Reveal test key' on the Secret key row, then copy it."ask_secret STRIPE_SECRET_KEY "Paste the secret key:"write_env STRIPE_PUBLISHABLE_KEY "$STRIPE_PUBLISHABLE_KEY"write_env STRIPE_SECRET_KEY "$STRIPE_SECRET_KEY"set_secret STRIPE_SECRET_KEY "$STRIPE_SECRET_KEY"   # CI needs this one# ──────────────────────────────────────────────────────────────────────────finish
查看另外 1 个位置
template.sh:195来自代码打开原文件
open_url "https://dashboard.stripe.com/test/apikeys"step "On the API keys page, copy the Publishable key (starts pk_test_)."ask STRIPE_PUBLISHABLE_KEY "Paste the publishable key:"step "Click 'Reveal test key' on the Secret key row, then copy it."ask_secret STRIPE_SECRET_KEY "Paste the secret key:"write_env STRIPE_PUBLISHABLE_KEY "$STRIPE_PUBLISHABLE_KEY"write_env STRIPE_SECRET_KEY "$STRIPE_SECRET_KEY"set_secret STRIPE_SECRET_KEY "$STRIPE_SECRET_KEY"   # CI needs this one# ──────────────────────────────────────────────────────────────────────────
中风险

持久化的秘密会以明文保存在默认 `.env` 文件中

原文依据:4 处
发现了什么

默认目标是当前目录的 `.env`,而 `write_env` 直接写入 `KEY=VALUE`。Skill 还要求对每个需要持久化的值调用该函数;隐藏终端输入只防止屏幕回显,并不加密磁盘内容。

为什么需要注意

能读取项目目录、备份、同步副本或误提交文件的人和进程可能获得 API 密钥。此实现没有在写入前确认目标文件是否被版本控制忽略。

秘密输入仅通过 `read -s` 隐藏终端回显;默认目标是当前目录的 `.env`,`write_env` 会把值作为普通 `KEY=VALUE` 文本写入。随附活动示例确实将 Stripe 秘密密钥传给该函数。若 `.env` 权限宽松、被备份或误提交,凭据可能暴露。用户可限制文件权限、确认 `.gitignore`,并要求只在确有本地持久化需求时写盘。

template.sh:25来自代码打开原文件
_STAGE_INDEX=0ENV_FILE="${ENV_FILE:-.env}"WRITTEN_ENV=()    # KEYs written to ENV_FILE this runWRITTEN_SECRET=() # secret NAMEs set this runSKIPPED=()        # things we couldn't do (e.g. gh missing)
查看另外 3 个位置
template.sh:128来自代码打开原文件
# write_env KEY VALUE upserts KEY=VALUE into ENV_FILE (creates it; replaces# any existing line). Idempotent.write_env() {  local key="$1" value="$2" tmp  touch "$ENV_FILE"  tmp=$(mktemp)  grep -vE "^${key}=" "$ENV_FILE" > "$tmp" || true  printf '%s=%s\n' "$key" "$value" >> "$tmp"  mv "$tmp" "$ENV_FILE"  WRITTEN_ENV+=("$key")  printf '  %s✓ wrote%s %s → %s\n' "$GREEN" "$RESET" "$key" "$ENV_FILE"}
template.sh:197来自代码打开原文件
ask STRIPE_PUBLISHABLE_KEY "Paste the publishable key:"step "Click 'Reveal test key' on the Secret key row, then copy it."ask_secret STRIPE_SECRET_KEY "Paste the secret key:"write_env STRIPE_PUBLISHABLE_KEY "$STRIPE_PUBLISHABLE_KEY"write_env STRIPE_SECRET_KEY "$STRIPE_SECRET_KEY"set_secret STRIPE_SECRET_KEY "$STRIPE_SECRET_KEY"   # CI needs this one# ──────────────────────────────────────────────────────────────────────────
template.sh:113来自代码打开原文件
# ask_secret KEY "Prompt" is like ask, but input is hidden.ask_secret() {  local key="$1" prompt="$2" current input  current=$(_existing "$key" || true)  if [[ -n "$current" ]]; then    printf '  %s%s%s %s[Enter keeps current]%s ' "$BOLD" "$prompt" "$RESET" "$DIM" "$RESET"  else    printf '  %s%s%s ' "$BOLD" "$prompt" "$RESET"  fi  read -rs input || true  printf '\n'  [[ -z "$input" && -n "$current" ]] && input="$current"  printf -v "$key" '%s' "$input"}
会不会删除文件或一直在后台运行?检查是否大范围删除文件、改写磁盘,或设置自动启动。发现 1 项风险
中风险

环境文件更新会替换文件本身,可能破坏符号链接和文件元数据

原文依据:2 处
发现了什么

`write_env` 先把内容复制到 `mktemp` 文件,再用 `mv` 把临时文件替换到 `ENV_FILE` 路径。这不是对原文件的原位修改。

为什么需要注意

如果 `.env` 是指向集中管理配置的符号链接,链接会被普通文件替换,而原目标保持旧值;现有文件的权限、所有者或其他元数据也可能改变。这可能造成应用继续使用旧凭据,或改变谁能访问配置。

`write_env` 把过滤后的内容写入 `mktemp` 创建的新文件,再以 `mv` 替换 `ENV_FILE` 路径,并非原位更新。若目标是符号链接,这通常会替换链接本身而不是其指向文件;新文件也可能继承临时文件权限而丢失原有权限、所有权或扩展元数据。该影响只在调用 `write_env` 时发生。用户可在运行前确认 `.env` 不是链接且备份其权限/元数据,或要求作者采用保留元数据的更新方式。

template.sh:130来自代码打开原文件
# any existing line). Idempotent.write_env() {  local key="$1" value="$2" tmp  touch "$ENV_FILE"  tmp=$(mktemp)  grep -vE "^${key}=" "$ENV_FILE" > "$tmp" || true  printf '%s=%s\n' "$key" "$value" >> "$tmp"  mv "$tmp" "$ENV_FILE"  WRITTEN_ENV+=("$key")
查看另外 1 个位置
template.sh:128来自代码打开原文件
# write_env KEY VALUE upserts KEY=VALUE into ENV_FILE (creates it; replaces# any existing line). Idempotent.write_env() {  local key="$1" value="$2" tmp  touch "$ENV_FILE"  tmp=$(mktemp)  grep -vE "^${key}=" "$ENV_FILE" > "$tmp" || true  printf '%s=%s\n' "$key" "$value" >> "$tmp"  mv "$tmp" "$ENV_FILE"  WRITTEN_ENV+=("$key")  printf '  %s✓ wrote%s %s → %s\n' "$GREEN" "$RESET" "$key" "$ENV_FILE"}
会不会绕过安全保护?检查是否跳过网站安全验证、开放过多文件权限,或取消操作前的确认。未发现风险
会不会误导 AI 或隐藏内容?检查工作说明是否要求 AI 忽略你的指令、干扰检查结果,或夹带看不见的文字。未发现风险
会不会偷偷改推广链接或收款方?检查是否强制替换推广链接或收款对象,同时要求隐瞒更改。未发现风险

Skill 逻辑拆解

1 个说明模块

该 Skill 会先检查项目中的环境变量文件、文档和 CI 工作流,再要求用户确认向导的阶段顺序、每个值的来源、写入位置以及是否属于秘密。

查看原文
SKILL.md:18来自说明文档打开原文件
Work out every manual step the human must take and every value that gets captured along the way. Read the repo first, don't ask cold:- For setup: `.env`, `.env.example`, `.env.*`, `README`, `docker-compose*`, framework config, and `.github/workflows/*` (every `secrets.*` / `vars.*` reference is a value the wizard must produce).- For a migration or transition: the current state, the target state, and the irreversible actions between them.Then show the user the ordered list of stages and the values each produces, and confirm: they may add, drop, or reorder.**Done when:** every stage is named in order, and for each captured value you know (a) where the human gets it, (b) where it's written (`.env`, a GitHub secret, both, or nowhere; some stages are pure actions), and (c) whether it's secret (hidden entry) or public.

生成的向导可以打开作者指定的网址,通过可见或隐藏输入收集值,并把这些值写入本地环境文件、GitHub Actions 仓库秘密或仓库变量。

查看原文
SKILL.md:35来自说明文档打开原文件
Copy `template.sh` to the target path. Replace the example stage with one `stage` per step, in dependency order. Use the library helpers: `stage`, `say`/`step`, `open_url`, `ask`/`ask_secret`, `write_env`, `set_secret`/`set_var`, `pause`/`confirm`. Set `TOTAL_STAGES` to the number of stages you wrote.Hold the bar the template sets: open the URL before asking for its value, use `ask_secret` for anything secret, `write_env` every persisted value, `set_secret` only the values CI actually needs, and `confirm` before any irreversible action. Each `stage` clears the screen so only the current step is visible: keep a stage to one focused task so nothing the human needs scrolls away. Don't touch the library above the marker.

Skill 明确要求不要由代理端到端运行向导,而应静态检查值的流向和 CI 秘密名称,并让用户自己运行。

查看原文
SKILL.md:41来自说明文档打开原文件
- `bash -n <script>`; run `shellcheck` if available.- `chmod +x <script>`.- Don't run it end-to-end yourself: it opens browsers and blocks on human input. Trace it statically instead: every value from step 1 is captured and lands where step 1 said, and every `set_secret` name exactly matches a `secrets.*` reference in CI.- Tell the user how to run it. If it's a repeatable setup path, commit it and link it from the README so the next person runs the script instead of asking an AI.

不可逆操作应由生成阶段显式调用确认函数;函数默认拒绝,只有输入以 y 或 Y 开头才继续。

查看原文
SKILL.md:37来自说明文档打开原文件
Hold the bar the template sets: open the URL before asking for its value, use `ask_secret` for anything secret, `write_env` every persisted value, `set_secret` only the values CI actually needs, and `confirm` before any irreversible action. Each `stage` clears the screen so only the current step is visible: keep a stage to one focused task so nothing the human needs scrolls away. Don't touch the library above the marker.
template.sh:83来自代码打开原文件
# confirm "question" is a y/N gate; returns success on yes.confirm() {  local reply=""  printf '  %s? %s [y/N] ' "$YELLOW" "$1"  read -r reply || true  [[ "$reply" =~ ^[Yy] ]]}
从这里开始 · 工作说明SKILL.md
wizard
连线表示工作说明包含的模块,不是实际运行顺序。点击模块可查看原文。

文件引用关系图

1 处引用
哪些文件发起引用引用了什么
连线表示真实的文件引用,不是运行顺序。点击节点可高亮相关连线,并查看具体文件和原文位置。虚线表示还有文件需要定位。
文件与检查记录3 个文件

检查范围与遗漏

逐文件查看涉及的内容

下方列出本次涉及的原文范围;纳入检查不代表已查清所有问题。

  • SKILL.md已纳入全文
  • template.sh已纳入全文
  • agents/openai.yaml已纳入全文

这份报告只针对上方版本。我们看了拿到的代码和说明文件,没有实际运行 Skill,也没有检查它另外安装的软件包。因此,这不是“保证安全”的承诺;换了版本或使用环境,结果也可能不同。

  • SKILL.md工作说明
  • agents/openai.yaml配套文件
  • template.sh脚本

代码和说明中提到的操作

运行命令
template.sh:1来自代码打开原文件
#!/usr/bin/env bash#
SKILL.md:3来自说明文档打开原文件
name: wizarddescription: Generate an interactive bash wizard that walks a human through steps only they can perform. Use when provisioning infrastructure, setting up credentials or CI secrets, walking an unfamiliar third-party dashboard, or running a one-off migration or cutover. Don't invoke this for steps the agent can perform itself.---
SKILL.md:8来自说明文档打开原文件
A **wizard** is a bash script that walks a human, step by step, through a manual procedure that's tedious to do by hand and tedious to re-explain to an AI every time. It opens each URL, says exactly what to click and copy, captures the values, writes them where they belong (`.env`, GitHub secrets), confirms at every stage, and shows how many stages are left. It might configure third-party services, run a one-off migration, or move the project from one state to another.
读取密钥或账号配置
template.sh:26来自代码打开原文件
_STAGE_INDEX=0ENV_FILE="${ENV_FILE:-.env}"WRITTEN_ENV=()    # KEYs written to ENV_FILE this run
template.sh:98来自代码打开原文件
# ask KEY "Prompt" reads a value into $KEY. Offers the existing .env value as# a default on re-runs (Enter keeps it). Visible input (non-secret).
template.sh:194来自代码打开原文件
say "We'll grab your Stripe test keys and store them for local dev + CI."open_url "https://dashboard.stripe.com/test/apikeys"step "On the API keys page, copy the Publishable key (starts pk_test_)."
修改文件
template.sh:136来自代码打开原文件
  printf '%s=%s\n' "$key" "$value" >> "$tmp"  mv "$tmp" "$ENV_FILE"  WRITTEN_ENV+=("$key")
连接外部网站
template.sh:194来自代码打开原文件
say "We'll grab your Stripe test keys and store them for local dev + CI."open_url "https://dashboard.stripe.com/test/apikeys"step "On the API keys page, copy the Publishable key (starts pk_test_)."
读取了多少行
254
文件校验值(用于核对版本)
dd770a3b52cf881a086256dd0e7cdbf8c5951e473142c2255f2c9848644ad1f3