mcpField
O
orca-sec-scans

orca-sec-scans

github.com/rheinmir安全10256 次安装2 周前更新
代码仓库

关于 orca-sec-scans

orca-sec-scans 是面向开发者和 CI 的只读安全扫描技能,结合 Trivy 静态检查、真实请求验证和可选的域名仿冒监测。它分别报告代码与运行环境中的风险,并要求对扫描结果进行复查,而不把静态扫描无发现等同于安全。

主要功能

  1. 01扫描依赖漏洞、配置错误和文件密钥
  2. 02生成 JSON 与 HTML 报告
  3. 03通过真实 HTTP 与 DNS 请求验证假设
  4. 04修复后重新扫描确认
  5. 05可选检测仿冒域名与证书

适用场景

  1. 01发布或合并部署分支前检查风险
  2. 02在 CI 中定期扫描代码库
  3. 03验证 API 身份验证与域名暴露情况
  4. 04检查品牌相似域名及其证书

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rheinmir/setup --skill orca-sec-scans

安装后在 Claude Code 中输入/orca-sec-scans确认已加载。

详细介绍

技能:orca-sec-scans

内容

用途和背景
  • **用途:**一个静态、只读的安全扫描流程(Trivy 扫描时不会修改代码),可在本地和 CI/Jenkins 中使用。覆盖:依赖项 CVE(Go/Node/Python 锁文件)、错误配置(Dockerfile/compose/nginx)以及文件中泄露的 secret。 除了这层静态扫描,还有两层:动态扫描通过真实请求验证开发者的默认假设;外部扫描(供应链/品牌、keyless)。
  • 触发条件(何时使用):
    • 用户提到“安全扫描”“scan”“trivy”“检查 CVE”“security scan”“有没有漏洞”
    • 发布前 / 合并部署分支前
    • 在 CI 中定期运行(trivy fs . --config trivy.yaml --exit-code 1)
    • Diff 涉及 Trigger-conditions 表中的内容(身份验证、用户输入、secret、新 endpoint、支付/敏感数据、将应用部署到 public domain)→ 必须扫描;用户提到“有没有漏洞”“安全吗”→ 始终触发。
  • **非目标:**当子模块有尚未提交的更改时,不自动批量升级;不从报告中删除 finding(接受后记录到 .trivyignore);不将报告提交到部署服务器;不进行 cti-expert 类型的大范围外部威胁调查(仅包含 supply-watch keyless 检查)。
心智模型

Trivy 是否已安装?→ 范围(锁文件)→ 静态扫描 HIGH/CRITICAL → JSON+HTML 报告 → 总结 + 修复建议 → 重新扫描 NONE,并行执行 开发者假设 → 真实请求(curl/dig/git diff)→ 确认或发现漏洞,可选执行 品牌名称 → 确定性变体 → 实时 DNS + CT 日志。静态扫描干净并不意味着安全。

输入和输出约定
字段必填?含义
输入源代码目录(be、fe 或 .)是扫描目标;如果仓库中有 trivy.yaml,则使用
输入正在运行的 HOST / domain动态扫描时需要用于通过 curl/dig 进行实际验证
输入品牌名称否用于 supply-watch.py
输出security/trivy-report.json + security/trivy-report.html是完整报告,仅作为审查 artifact
输出按目标分类的 HIGH/CRITICAL 表格 + 修复建议是升级 deps、使用非 root 的 USER、轮换 secret
输出动态扫描结果是逐项列出假设:成立/不成立,并附命令 + 实际 HTTP/DNS 代码
输出重新扫描结果有修复时remaining = NONE
输出supply-watch 报告可选rc 0 表示干净,2 表示有发现;crt.sh 出错 → 跳过
规则和能力
  • RULE-01(必须):**静态(Trivy)和动态(上述检查清单)是两个不同的层面——两者都要运行。**Trivy 能发现 CVE/错误配置/文件中的 secret,但无法发现身份验证绕过、公开暴露、CORS/CSRF 逻辑问题、分支不一致。不要把 Trivy 报告干净视为安全。
  • RULE-02(必须):不要相信开发者的默认假设——所有“已经有登录”“内部使用所以安全”“已经能运行”等说法,都必须先通过真实请求验证,才能下结论。
  • RULE-03(必须):Trivy 扫描时不会修改代码——可随时安全运行。
  • RULE-04(必须):已审查并接受的 finding → 记录到 .trivyignore(每行 1 个 ID + 原因注释 + 日期),不要从报告中删除。
  • RULE-05(必须):不要将 security/*.json|html 提交到部署服务器——它们仅作为审查 artifact。
  • RULE-06(必须):部署 bonbon-ai 时:只将 be 和 fe(2 个子模块)推送到服务器;工具文件(trivy.yaml、security/、skill)不推送到服务器。
  • RULE-07(必须):所有修复更改都必须在提交前通过构建/验证(go build ./...、pnpm i 等)。
  • 能力:缺少本地扫描工具时可安装;以只读方式扫描源代码;向项目自身的 host 发送真实 HTTP/DNS 请求;在获准应用修复时修改 manifest/Dockerfile;读取公开 CT 日志/DNS(keyless)。
失败边界
  • 无法安装 Trivy → 阻塞,告知用户。
  • 子模块有尚未提交的更改 → 仅提出修复建议,不自动升级。
  • 修复后无法构建(go build ./...、pnpm i)→ 失败,不提交。
  • 没有可用于动态扫描的 HOST → 部分完成:仅进行静态扫描,明确说明动态层尚未运行,不要得出“安全”的结论。
  • secret 被标记 → 立即轮换 key(不能只从文件中删除)。
  • supply-watch 无法调用 crt.sh → 跳过,不要断言扫描干净。

操作

主工作流
步骤类型输入操作输出/退出失败/后续
W01effect机器步骤 0 — 检查并安装 Trivy(必须先运行)输出 trivy --version安装失败 → blocked
W02deterministic仓库步骤 1 — 通过 lockfile 检测语言,排除 build/vendor 目录scope—
W03deterministicscope步骤 2 — 扫描漏洞、错误配置和机密,优先处理 HIGH/CRITICALfindings—
W04deterministicfindings步骤 3 — 将 JSON + HTML 报告输出到 security/2 个报告文件—
W05judgmentfindings步骤 4 — 按 target 汇总 HIGH/CRITICAL 并提出修复建议表格 + 建议子模块有未提交更改 → 仅提出建议
W06deterministic已修复的 target步骤 5 — 重新扫描以确认remaining = NONE仍有问题 → 返回 W05
W07effectHOST、diff动态扫描:使用真实请求运行 8 项开发假设检查清单每项假设均有证据没有 HOST → partial
W08deterministic品牌名称使用 supply-watch.py(B03)进行外部扫描rc 0 或 2crt.sh 出错 → 跳过

各步骤详情(W01–W08 的事实来源):

工作流
步骤 0 — 检查并安装 Trivy(必须先运行)
if ! command -v trivy >/dev/null 2>&1; then
  echo "Trivy chưa có → cài…"
  if [[ "$(uname)" == "Darwin" ]]; then
    brew install trivy
  else
    # Linux: dùng script chính thức Aqua (không cần root nếu set BINDIR)
    curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \
      | sh -s -- -b /usr/local/bin
  fi
fi
trivy --version   # xác nhận; DB vuln tự cập nhật lần chạy đầu
步骤 1 — 检测语言(扫描范围)

查找 lockfile 以确定生态系统:go.sum/go.mod(Go)、package-lock.json/pnpm-lock.yaml(Node)、requirements.txt/poetry.lock(Python)。排除 node_modules、.next、.contentlayer、_archives、.git。

步骤 2 — 扫描(优先处理 HIGH+CRITICAL,以加快速度)
trivy fs <dir> \
  --scanners vuln,misconfig,secret \
  --severity HIGH,CRITICAL \
  --skip-dirs '**/node_modules' --skip-dirs '**/.next' \
  --skip-dirs '**/.contentlayer' --skip-dirs '_archives' \
  --no-progress

bonbon-ai 仓库:分别扫描 be 和 fe(各自都是子模块)。如果仓库已有 trivy.yaml,优先使用 --config trivy.yaml。

步骤 3 — 输出完整报告
mkdir -p security
TPL=$(find $(brew --prefix trivy 2>/dev/null || echo /opt/homebrew) -name html.tpl 2>/dev/null | head -1)
trivy fs . <cờ skip-dirs như trên> --no-progress -f json     -o security/trivy-report.json
trivy fs . <cờ skip-dirs như trên> --no-progress -f template --template "@$TPL" -o security/trivy-report.html
步骤 4 — 汇总并提出修复建议

按 target 统计 HIGH/CRITICAL,并打印表格。随后提出建议(如果子模块有未提交的更改,不要批量自动升级依赖):

  • 容易升级的依赖(直接依赖,直接修改 manifest):例如 requirements.txt 中的 python-multipart。
  • 间接依赖:运行 go get <pkg>@<ver>,然后运行 go build ./... 验证。注意,go get 可能会提高 go 指令的版本;如果超过 Dockerfile 中的基础镜像版本,也要相应升级 FROM golang:X-alpine。
  • 错误配置 DS-0002(root 用户):在 Dockerfile 中添加非 root 用户 USER(Alpine 使用 adduser -D,Debian 使用 useradd -m,或者对 node-alpine 镜像使用 USER node;记得对 volume/data 等可写目录执行 chown)。
  • 机密:如果 Trivy 报出机密,立即轮换密钥,不要只从文件中删除。
步骤 5 — 重新扫描以确认

在已修复的 target 上重新运行步骤 2,确认 remaining = NONE。

外部扫描 — 供应链与品牌(第三条路径,无需密钥)

上面两部分都是从项目内部向外看,没有任何部分从外部向内看:是否有人搭建了与你的名称相似的域名或 package 来欺骗用户,或将虚假依赖插入你自己的安装命令中。

python3 fdk/tools/supply-watch.py <tên-thương-hiệu>            # sweep mặc định 7 TLD
python3 fdk/tools/supply-watch.py <tên> --tld com,dev --json   # cho CI
python3 fdk/tools/supply-watch.py --self-test

按六种模式生成确定性、离线变体——删字、重复字母、倒序、误按相邻按键(QWERTY 键盘)、形似字符替换(o→0、l→1)、添加连字符——然后查询 DNS,检查哪些仍在运行。同时使用 CT monitor 读取 Certificate Transparency(crt.sh),查看是否有证书刚刚签发给相似域名。

无需 API key,也无需 .venv。退出码:0 表示干净,2 表示有发现。如果无法连接 crt.sh,会提示跳过,不会断言结果干净。

从 7onez/cti-expert(工作流 08)中少量吸收功能。有意只取这一小部分:cti-expert 有 121 个 op 和 78 个 MCP 工具,用于调查外部威胁,需要 .venv、API key 和出站网络。整体合并会把密钥和网络依赖引入一个原本无需密钥且可离线运行的入口。

动态扫描 — 验证开发者假设(补充 Trivy)

原则:Trivy(静态扫描)无法发现架构、逻辑或运行时配置错误。 最严重的漏洞往往藏在开发者的默认假设中——必须通过真实请求验证,不能轻信。“能运行”≠“安全”。

源自 2026/06/22 的事故复盘:薪资 ETL API 没有身份验证(身份验证只在 Web 层,/etl 路径经 nginx 绕过)→ 任何人都能通过 curl 获取薪资和 3,637 名员工的 PII;以为是“内部服务”,但它有公共域名 devtingting.coteccons.vn(公共 IP),可桥接到整个互联网。Trivy 没有发现问题——只有实际执行 curl/dig 才能查出。

“别轻信——必须验证”清单(开发者假设 → 实际情况 → 验证方法)
  1. “反向代理后的 API 有保护,因为 Web/UI 有登录。” → 错:身份验证通常只在 Web 层;代理路径(/etl、/api 等)可由浏览器直接调用,因此会绕过登录。 → 验证:对每个 API 路由直接执行 curl,不附带 cookie/token → 必须返回 401。如果返回 200+数据,就是漏洞。身份验证必须在 API/代理层实现(例如 nginx auth_request),不能只在 UI 实现。

    for p in data/stats/all report/export sync/status; do
      curl -k -o /dev/null -w "$p -> %{http_code}\n" https://HOST/etl/$p; done   # mong đợi 401
    
  2. “服务器是内部服务器 / 私有 IP(192.168.x),所以外部无法访问。” → 错:公共域名、tailscale funnel 或端口转发都可能搭建通路。 → 验证:dig +short <所有可能的子域名> → 是否有公共 IP?尝试从外部网络执行 curl。不要轻信“内部”这一说法——检查实际 DNS。

  3. “开放 CORS 就是漏洞 / 关闭 CORS 就足够安全。” → 方向错:CORS 只会阻止跨域浏览器读取。它不会阻止 curl/脚本,也不会阻止 CSRF 写入(POST 查询参数 / 无请求体属于 简单请求 → 不会预检 → 无论 CORS 配置如何,服务器都会执行)。真正的漏洞通常是没有身份验证 + 端口开放。主入口(身份验证)还没锁好之前,别浪费时间折腾 CORS。

  4. “保留默认配置没问题。” → 检查默认值是否进入生产环境:CORS_ORIGINS 还留着 localhost:3000 吗?secret/flag 还用着示例值吗?BIND_HOST 是否意外设成了 0.0.0.0?

    curl -k -D- -o /dev/null -H "Origin: http://localhost:3000" https://HOST/etl/health | grep -i access-control
    
  5. “部署哪个分支都一样。” → 错:CI(Jenkins)克隆分支 X,但服务器运行分支 Y → 两者不一致。合并冲突可能导致整个代码块丢失(例如 compose 中的 networks: → undefined network,部署失败)。 → 验证:CI 克隆的分支是否与正在运行的分支一致?git diff <ci-branch> <running-branch> -- docker-compose.yml .env* deploy/。

  6. “paramiko/SSH 能连接就行。” → Transport(...) / AutoAddPolicy 不会验证主机密钥 → 中间人攻击(MITM)可窃取密码和文件。验证:必须固定 known_hosts 并使用 RejectPolicy。

  7. “Token/secret 怎么传都行。” → Token 放在 URL ?token= 中 → 会进入 nginx/uvicorn 访问日志、Referer 和历史记录。验证:secret 必须通过请求头/cookie传递,不能放在查询字符串中。

  8. “用 SELECT * 比较方便。” → 会返回包含 PII 的所有列(CCCD/MST/BHXH/薪资);全列搜索还会成为探测数值的预言机。验证:对返回列使用白名单;搜索时不要扫描敏感列。

触发条件 — 哪些代码行为必须扫描

不必等人记得调用技能——diff 命中表中任一项,就必须触发扫描(根据 WorldFlowAI/everything-claude-code security-review 提炼):

刚完成的更改必须执行原因
添加/修改身份验证、会话、权限Trivy + 动态扫描Token 存在 localStorage 中会受到 XSS 影响,敏感操作前缺少角色检查——授权层的错误是 Trivy 无法发现的。
接收用户输入(表单、参数、上传)Trivy + 动态扫描输入未通过 schema 验证 + 文件上传未限制 size/type/extension,都是 SQLi/XSS/RCE 的入口。
涉及 secret / credential / API keyTrivy(secret scan)Key 硬编码在 source 中或进入 git history——必须放在 env var 和平台 secret 中,.env 必须加入 gitignore。
新增 API endpointTrivy + 动态扫描新 endpoint 默认缺少 rate-limit + CSRF + 权限检查;错误消息容易泄露内部详情/stack trace。
支付 / 敏感数据Trivy + 动态扫描 + 人工审查PII/资金不得写入 log,错误信息必须通用;一个漏洞就可能危及整个平台——宁可谨慎行事。
将 app 发布到 public domain / 更改 reverse proxy动态扫描“内部”免认证漏洞会在此刻暴露到互联网(上面的 checklist 假设开发环境)。

不符合表中任一项 → 按发布节奏扫描即可。自检问题:“这个 diff 是否涉及上述 6 项中的任何一项?”——不到一分钟就能回答。用户说“有没有漏洞”“安全吗”→ 一律视为触发条件。

分支
ID类型条件行为跳过 / 失败汇合
B01conditional_requiredrepo bonbon-ai分别扫描 be 和 fe(二者都是 submodule);部署时只推送这 2 个 submodule其他 repo → 扫描 .W04
B02conditional_requiredrepo 已有 trivy.yaml优先使用 --config trivy.yaml没有 → 默认使用 skip-dirs 标记W04
B03user_optional用户想检查供应链 / 品牌supply-watch.py <名称> 扫描 7 个 TLD + CT 监控无此要求 → 跳过结束
B04conditional_requiredfinding 已审查并接受写入 .trivyignore(每行 1 个 ID + 原因 + 日期),不得从报告中删除—W06
B05conditional_requiredTrivy 标记了 secret立即轮换 key,不能只从文件中删除—W06
验证与停止条件

必须验证:Trivy 的 rc/output(重新扫描后 remaining = NONE)、curl 的真实 HTTP 状态码(API route 不带 token 时必须返回 401)、真实的 dig 结果、分支的 git diff、supply-watch.py 的 rc。只有 build/verify 成功后才能提交修复。需要人工处理:决定是否在 .trivyignore 中接受 finding,人工审查支付/敏感数据流程。重新扫描干净且 checklist 中的所有假设都有证据后即可停止;不能仅凭 Trivy 就得出“安全”的结论。

示例
  • 正例:“扫描 bonbon-ai repo 的安全性”→ 已有 Trivy → 分别扫描 be、fe → 发现 2 个 HIGH:requirements.txt 中的 python-multipart + DS-0002 root 用户 → 升级依赖 + 添加 USER node → build 成功 → 重新扫描后 remaining = NONE;动态扫描时 curl /etl/data/stats/all 不带 token,返回 401。
  • **边界/失败:**Trivy 扫描干净,但直接 curl /etl/report/export 不带 cookie 却返回 200 + 工资数据 → 这是 auth-bypass 漏洞,即使静态扫描报告干净也要严重上报(RULE-01);dig +short 子域名得到 public IP → “内部”这一说法不成立。
  • **边界:**运行 supply-watch.py acme 时,如果 crt.sh 无响应 → CT 监控打印跳过,不得报告扫描干净。

来源

  • **2026-07-17 吸收(adapt_mode: dissolve,T-260717-02):**触发条件表根据 WorldFlowAI/everything-claude-code 提炼(skills/security-review/SKILL.md — When to Activate + 10 类 checklist)。在 scratchpad/ 中以 depth-1 克隆,未 vendoring 字节内容。

评论

支持 Markdown