mcpField
S
scan-site

scan-site

github.com/microsoft安全1.1k151 次安装今天更新
代码仓库

关于 scan-site

scan-site 是面向 Power Pages 项目的安全技能,可扫描已部署的网站、获取最新报告并概述发现。它检查线上站点,而非本地源代码。

主要功能

  1. 01扫描已部署的 Power Pages 网站
  2. 02检查扫描状态和最新报告
  3. 03用通俗语言概述发现
  4. 04生成 HTML 报告
  5. 05建议后续安全技能

适用场景

  1. 01查看网站当前的安全问题
  2. 02扫描已部署的网站
  3. 03以 HTML 报告分享扫描结果

安装

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

$npx skills add https://github.com/microsoft/power-platform-skills --skill scan-site

安装后在 Claude Code 中输入/scan-site确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
commands.md
scan-reference.md
scripts/
get-latest-report.js
poll-deep-scan.js
start-deep-scan.js
transform-report.js

详细介绍

插件检查:运行 node "${PLUGIN_ROOT}/scripts/check-version.js" — 如果输出了消息,请在继续之前向用户显示该消息。

扫描站点

对已部署的 Power Pages 站点运行安全扫描,获取最新扫描报告,并以通俗易懂的摘要呈现发现结果。扫描在服务器端运行;耗时取决于站点规模——小型站点几分钟即可完成,大型站点可能需要数小时。

此技能扫描的是实时部署的站点,而不是本地源代码。

初始请求: $ARGUMENTS

注意事项

  • 网站记录 ID 与门户 ID。 .powerpages-site/website.yml 存储的是网站记录 ID,而不是门户 ID。每个脚本都需要 --portalId。在前置步骤中使用 website.js --websiteId 解析一次。
  • 切勿按名称解析。 环境内的站点名称可能重复;只有网站记录 ID 是安全的。
  • 解析器返回 null 表示站点尚未部署,或已通过身份验证的配置文件指向了其他环境。
  • 扫描耗时较长。 耗时取决于站点规模——小型站点几分钟即可完成,大型站点可能需要数小时。在后台轮询,大型站点请增大 --timeoutMinutes。
  • 同一站点一次只能运行一个扫描。 如果有扫描正在运行时启动新扫描,会返回 Z003 — start-deep-scan.js 会将其报告为 { "status": "already-running" }(退出码为 0)。
  • 可能会受到速率限制。 服务可能会限制对同一站点重复扫描的频率。遇到限流时,请等待后再重试。
  • 尚无已完成的扫描。 新站点或正在扫描的站点没有已完成的报告 — get-latest-report.js 会返回 { "status": "empty" }。

工作流

  1. 前置步骤 — 定位项目、确认已登录、识别站点
  2. 检查扫描状态 — 检查是否有扫描正在运行
  3. 选择操作 — 提供结合上下文的建议(运行新扫描 / 显示最新结果)
  4. 运行扫描 — 启动扫描并轮询直至完成
  5. 获取并总结 — 获取报告并呈现发现结果
  6. 逐项处理后续事项 — 将问题转交给合适的下游技能(仅当报告中包含问题时)

任务跟踪

创建四组任务。每项任务开始时标记为 in_progress,完成后标记为 completed。

组创建时机任务
1开始时检查前置条件
2前置条件通过后检查扫描状态 · 选择操作(审核模式下跳过)
3用户确认操作后(或处于审核模式时)运行扫描(仅在交互模式下用户选择查看最新结果时跳过) · 获取并总结(始终执行)
4获取并总结后逐项处理后续事项(仅当报告包含问题且不处于审核模式时)

1. 前置步骤

1.1 定位项目并检测审核模式

使用 Glob 查找 **/powerpages.config.json。如果 $ARGUMENTS 包含 --review <out-dir>,请记住输出目录 — 跳过第 3 步(选择操作),自动执行第 4 步(运行扫描,启动新扫描或连接到正在运行的扫描),第 5 步仅写入 JSON,并跳过第 6 步(后续事项)。

1.2 解析站点标识符

读取 .powerpages-site/website.yml → 提取 id 字段 → 即为 <WEBSITE_ID>。

如果缺少该字段,则站点尚未部署。告知用户并建议运行 /deploy-site。停止。不要按名称或 URL 解析。

解析为 portalId:

node "${PLUGIN_ROOT}/scripts/website.js" --websiteId "<WEBSITE_ID>"

记录 Id(portalId)、Type、Name、WebsiteUrl。如果退出码为 2 → 需要登录(pac auth create 或 az login)。如果为 null → 在此环境中找不到站点。两种情况都应停止。


2. 检查扫描状态

node "${PLUGIN_ROOT}/skills/scan-site/scripts/poll-deep-scan.js" --portalId "<PORTAL_ID>" --once

--once 执行一次状态检查,退出码为 0,并输出:

  • { "status": "ongoing" } → 当前有扫描正在运行。
  • { "status": "idle" } → 没有扫描正在运行。

然后调用 get-latest-report.js,确认是否存在已完成的报告:

node "${PLUGIN_ROOT}/skills/scan-site/scripts/get-latest-report.js" --portalId "<PORTAL_ID>"

{ "status": "ok" } 表示有可用报告。{ "status": "empty" } 表示尚无已完成的扫描。


3. 选择操作

在审查模式下跳过,直接进入第 4 步(该步骤始终会在审查模式下运行)。

必须只使用通俗易懂的语言。绝不要使用 CSP、CORS、OWASP、hardening 或 scan profile 等词。

默认方案

🚦 关卡(计划 · scan-site:3.action-choice): 根据网站的扫描状态(运行中、空闲、有报告、无报告)推荐一项操作,然后询问用户是接受还是另选操作。开始新扫描会触发持续数分钟的后端任务;使用现有报告不收费。

触发条件: 进入阶段 3(仅交互模式——审查模式会跳过此步骤,直接进入第 4 步)。 询问原因: 如果近期报告已经能回答问题,自动开始新扫描会浪费数分钟;如果自动使用过时报告,则会遗漏近期发现。 取消后: 无任何变化——不会触发扫描,也不会使用报告。

分析网站的当前状态,并通过 AskUserQuestion 推荐最相关的一项操作:

  • 扫描正在运行,且没有已完成的报告 → 建议等待当前扫描完成。
  • 扫描正在运行,且已有报告 → 建议在新扫描继续运行时查看最新结果。
  • 空闲,且没有已完成的报告 → 建议运行新扫描。
  • 空闲,且有近期报告 → 询问用户是使用现有报告,还是运行新扫描。

如果网站状态不足以支持具体建议,就不要强行推荐;询问用户想要进行什么操作。

选项规则

通过 AskUserQuestion 提供选项时:

  • label 保持在 1–5 个词。每个选项都要包含 description。
  • 对于会触发新扫描的选项,请在该选项的 description 中说明相关注意事项,确保用户在决定时了解这些信息。用户选择该选项后,不要再单独询问确认。
  • 仅当选项代表具体变更(开始新扫描)时才包含 preview。不要为“显示最新结果”或信息类选项添加 preview。
  • 只显示当前状态下可执行的选项。如果扫描已在运行,不要提供“开始新扫描”。
  • 仅当网站状态支持时才标记“(推荐)”。

4. 运行扫描

在审查模式下,始终执行此步骤:如果扫描已在运行,则接入该扫描并轮询;否则开始新扫描并轮询。不要询问——审查模式会在无需用户交互的情况下端到端运行。

在交互模式下,如果用户选择查看最新结果,则跳过此步骤。

开始扫描:

node "${PLUGIN_ROOT}/skills/scan-site/scripts/start-deep-scan.js" --portalId "<PORTAL_ID>"

如果标准输出为 { "status": "already-running" },则跳转到轮询步骤——已有扫描正在进行。

然后轮询,直至扫描完成:

node "${PLUGIN_ROOT}/skills/scan-site/scripts/poll-deep-scan.js" --portalId "<PORTAL_ID>"

使用 run_in_background: true 运行轮询,以便用户继续工作。脚本会在扫描完成或超时后退出(默认 20 分钟)。如果超时,则获取当前可用的报告,并在摘要中注明超时。


5. 获取并总结

5.1 获取并转换报告
node "${PLUGIN_ROOT}/skills/scan-site/scripts/transform-report.js" --portalId "<PORTAL_ID>"

解析标准输出中的 JSON。状态字段可能为:

  • ok — 正常报告,包含 findings 和 details。
  • empty — 此网站没有已完成的扫描(例如,网站刚创建或扫描仍在运行)。记录一条说明此情况的 info 发现,然后继续。
  • malformed — API 返回的响应缺少 Rules 数组。转换过程会生成一条描述此情况的 warning 发现;将其呈现给用户,并建议重新运行扫描。

有关脚本应用的 Risk → 严重性映射,请参阅 references/scan-reference.md。

5.2 审查模式

在审查模式下,跳过 HTML 报告,并将转换后的标准输出写入 <REVIEW_DIR>/scan-site.json。然后停止。转换过程会生成 { status, findings, details };编排技能负责呈现结果。

5.3 渲染 HTML 报告

在审核模式下跳过。

渲染时使用与汇总安全审核相同的共享模板。构建包含单个部分的审核数据负载,然后进行渲染:

node "${PLUGIN_ROOT}/scripts/build-review-data.js" \
  --reportName "Site Scan" \
  --inputDir "<TEMP_DIR>" \
  --siteName "<SITE_NAME>" \
  --goalLabel "Live Site Scan" \
  --scopeLabel "<SCOPE_LABEL>" \
  --summary "<SUMMARY_TEXT>" \
  --output "<TEMP_DIR>/data.json"

node "${PLUGIN_ROOT}/scripts/render-review.js" \
  --data "<TEMP_DIR>/data.json" \
  --output "<PROJECT_ROOT>/docs/site-scan-<YYYY-MM-DD-HHMMSS>.html"

<TEMP_DIR> 中只能包含 scan-site.json(第 5.1 步的转换输出)——build-review-data.js 会忽略中间文件。文件名必须包含本地时间戳(例如,site-scan-2026-05-14-053805.html)。渲染成功后删除 <TEMP_DIR>。在浏览器中打开渲染后的 HTML。

5.4 提供摘要

在聊天中用通俗易懂的语言总结:发现总数、按严重程度分类的数量,以及可能的自上次扫描以来的变化。不要一开始就提技术名称。

5.5 记录技能使用情况

参考:${PLUGIN_ROOT}/references/skill-tracking-reference.md

使用 --skillName "ScanSite"。


6. 引导后续操作

在审核模式下跳过。如果报告中没有问题,也跳过。

按可提供帮助的下游技能对发现进行分组:

  • 标头 / Cookie 问题 → /manage-headers
  • WAF / 防火墙问题(阻止机器人、限制页面访问频率、限制 IP / 国家或地区)→ /manage-firewall
  • 权限问题 → /audit-permissions 检查现有表权限,和/或 /create-webroles 设置基于角色的访问权限
  • 登录或外部身份问题 → /setup-auth
  • 代码层面的问题(暴露的调试页面、信息泄露、源代码公开可见)→ 建议手动修复代码;没有可用于处理这些发现的路由技能

只建议与报告中实际存在的发现相匹配的技能。如果某项发现不对应任何技能,应将其作为用户可采取行动的手动后续事项提出。如果没有有意义的后续操作,则结束该技能——不要为了提问而提问。


约束

  • 通俗易懂——绝不能对用户使用技术术语。使用日常用语;只有在用户询问时才解释技术名称。
  • 只读——此技能只运行扫描并读取结果。它不会启用 WAF、删除扫描或更改网站配置。
  • 后台长时间运行的调用——启动扫描后,通过 run_in_background: true 轮询,以便用户继续工作。
  • 结合上下文进行交互——每项建议都必须反映网站的当前状态:
    • 当扫描正在运行时,绝不要提供“开始新扫描”。
    • 没有已完成的报告时,绝不要提供“显示最新结果”。
    • 只有当前状态支持时,才标注“(推荐)”。
  • 预览仅用于审查更改——仅在会启动新扫描的选项中包含 preview。不要将其添加到导航或信息类选项中。

参考资料

  • references/commands.md——脚本标志、响应结构、错误目录和操作说明。脚本返回非零退出代码时,请阅读“常见错误目录”一节。
  • references/scan-reference.md——深度扫描报告的字段级架构、警报风险值、规则状态和严重程度映射。规范化发现时请阅读。

评论

支持 Markdown