urlscan-release v3.0.7
URLScan CLI
从源码中提取攻击面:端点、参数、shadow API、移动端 deep link —— 同一份清单服务人工审计、AI 审计与 DAST。
这个工具解决什么问题
在做安全测试、代码审计、接口梳理或资产盘点时,我们首先要回答一个问题:
这个项目到底暴露了哪些入口?
这些入口可能是:
- Web API:
GET /api/users/{id}、POST /login - 管理接口:
/admin/* - 文件上传接口:
/upload - GraphQL、WebSocket、RPC、OpenAPI、Postman 集合中的接口
- Android / HarmonyOS deep link 等移动端入口
- CLI,如 hdc cli 对外支持哪些命令入参
传统做法通常有几个问题:
| 做法 | 问题 |
|---|---|
| 人工看代码 | 慢,容易漏,混合技术栈项目更难看全。 |
| 靠爬虫 | 只能发现运行时能访问到的页面和接口,隐藏接口、鉴权后接口、未部署接口容易漏。 |
| 靠接口文档 | 文档可能过期,代码和文档不一致。 |
| 每个框架单独写脚本 | 维护成本高,结果格式不统一。 |
| AI 挖掘工具(如 Turing) | 依赖 LLM 按关键字搜索提取端点,大型项目上容易关键字遗漏、模型偷懒甚至幻觉,完整性无保证。 |
| 专用静态工具(如初代 URLScan) | 只覆盖特定框架 / 语言,面对内部复杂混合技术栈的项目,容易留下扫描盲区。 |
从 URLScan 到 URLScan CLI。 表中最后一行说的正是我们自己的初代工具:URLScan 最早是一款 IDEA 插件,只扫描内部 Java 框架。它早已前移接入流程 IT 流水线,累计支撑产品线揭示 3w+ 问题;但"只覆盖特定框架 / 语言"的天花板始终存在,面对内部复杂的混合技术栈,盲区不可避免。于是我们全新重写了 URLScan CLI 静态扫描引擎:50+ 框架、30+ 语言与平台,统一输出 endpoint 清单,专为适配 AI 工具输入而设计 —— 先把入口找全,AI 审计才谈得上不漏。
URLScan CLI 的目标是:
直接扫描源码,静态发现攻击面,输出一份统一的 endpoint 清单。
flowchart LR
Code["源码仓库"] --> Scan["URLScan CLI 静态扫描"]
Scan --> Endpoints["统一 Endpoint 清单"]
Endpoints --> Security["安全测试"]
Endpoints --> Audit["代码审计"]
Endpoints --> Report["JSON / SARIF / OpenAPI / HTML"]
具体来说,URLScan CLI 读取源码即可提取应用对外暴露的端点 —— 路径、方法、参数、请求头、Cookie,以及背后的源文件。Shadow API、废弃路由、未文档化的处理器都会出现在同一份清单里,无需单独的模式。
一份清单,服务谁
- 人工审计。 安全工程师与代码审计员拿到一份聚焦的、攻击者可达的入口点清单(路径、参数、源文件、标签),而不是通读整个仓库。
- AI 审计。 基于 LLM 的 SAST Agent 拿到同一份清单,外加每个端点的 review 上下文(
--include callee取 1 跳被调用者,--ai-context取 guards / sinks / validators / signals);静态规则未覆盖的框架,也可交给 LLM 兜底分析。
先看一组真实数字:盘点 Apache CXF
光说原理不够直观。拿一个大家都熟悉的真实项目做一次完整盘点 —— Apache CXF,开源企业级 Java Web 服务框架(JAX-WS / JAX-RS),体量与一般企业 Java 项目相当:
| 维度 | 数字(2026-07-31 实测) |
|---|---|
| 代码规模 | 10,491 个 Java 源文件(全仓 3.2 万个文件) |
| 攻击面 | 1,979 个端点(SOAP/WSDL 1,197 + CXF/JAX-RS 768 + JSP 等 14) |
盘点这 1,979 个端点,三种方式的成本对比:
| 方式 | 耗时 | 产出 | 备注 |
|---|---|---|---|
| 人工梳理 | 约 1~2 周 * | 手工表格 | 口径:按每个端点 1.5~3 分钟溯源 —— 定位声明文件、确认 @Path 拼接、记录方法与参数;JAX-RS 注解继承、子资源定位符最耗神 |
| 裸用 LLM | 小时级 ~ 1 天 + 人工复核 | 问答记录 | 1 万+ 源文件远超上下文窗口,需人工切片喂入;靠关键字搜索提取容易遗漏,模型还会偷懒、产生幻觉,注解继承、规格与实现的关联尤其易漏,完整性无保证 |
| URLScan CLI | 约 118 秒(实测) | 1,979 个端点的统一 JSON,每个端点带源码文件与行号 | 全量覆盖、结果可复现,SOAP 与 REST 双面同时出 |
* 估算口径已标注,欢迎用你们自己的项目复算。
值得一提的是 URLScan CLI 与 AI 的关系:它不是要替代 LLM,而是给 LLM 审计补盲区 —— 上面这份清单加上 --ai-context 聚合的 guards / sinks / validators,正是 LLM 审计 Agent 最需要的输入。先把入口找全,AI 审计才谈得上完整。
Java 只是例子。Go / Python / JS / Rust / PHP / 移动端…… 50+ 框架,同一条命令,同一份清单。
总体链路图
整个扫描过程可以理解成一条流水线:
flowchart LR
CLI["CLI 输入"] --> Detect["Detect 识别技术栈"]
Detect --> Locator["CodeLocator 文件索引"]
Locator --> Analyze["Analyze 提取接口"]
Analyze --> Optimize["Optimizer 清洗去重"]
Optimize --> Output["Output 生成报告"]
每一步的作用:
| 阶段 | 通俗解释 | 产出 |
|---|---|---|
| CLI | 用户指定要扫哪个目录、输出什么格式。 | 扫描配置 |
| Detect | 先判断项目用了哪些语言和框架。 | 技术栈列表 |
| CodeLocator | 建立统一文件清单和缓存,避免重复扫文件。 | 文件索引 |
| Analyze | 按技术栈调用对应分析器,从源码中提取路由。 | 原始 endpoints |
| Optimizer | 去重、规范 URL、补全路径参数。 | 干净的 endpoint 清单 |
| Output | 输出成 JSON、SARIF、OpenAPI、HTML、Mermaid 等格式。 | 报告或下游工具输入 |
每个框架的接入都遵循同一套分层 —— Detector 识别技术栈;语言引擎 + 路由提取器 共享文件遍历与解析(Go / Java / Kotlin / Python 用 Tree-sitter 做 AST 级提取,而不是拿正则碰运气);框架适配层 只是百行级的参数映射薄层。新增框架不需要触碰公共代码 —— 这正是下面 TDD 故事能成立的前提。
快速上手
编辑器插件最省心(见文末"5 分钟上手");CLI 适合流水线与批量扫描:
# 构建 CLI(需 Crystal ~> 1.19、libyaml、libzstd),产出 bin/urlscan
shards install && shards build
# 或用 Docker 构建一致环境
docker run --rm -v $(pwd):/app -w /app crystallang/crystal:1.19.0-alpine \
sh -c "apk add --no-cache yaml-dev zstd-dev && shards install && shards build"
urlscan -b path/to/source # 基础分析
urlscan -b . -f json # JSON 输出
urlscan -b . -P # 被动安全扫描
urlscan -b . --send-proxy http://127.0.0.1:8080 # 转发到代理(Burp/ZAP)
urlscan -b . --ai-provider openai --ai-model gpt-4 # AI 辅助分析
一次真实扫描的终端输出:

若使用 GitHub Action,请参考 GitHub Action 文档。完整使用文档见 docs/content/usage/。
支持的框架
URLScan CLI 支持 50+ 框架、30+ 语言与平台。完整功能矩阵(endpoint / method / query / path / body / header / cookie / static / websocket / callee / AI Context 的 chip 详情)见 language_and_frameworks/index.md。下方表格复用该索引的数据(重点支持的移动 / 鸿蒙 / Java 企业框架置顶,其余按语言分组):
| 语言 / 平台 | 框架 |
|---|---|
| 重点支持(移动 / 鸿蒙 / Java 企业) | Android, HarmonyOS (Deep Link), HarmonyOS SA (RPC), Jalor, ServiceComb, Apache CXF (JAX-WS / JAX-RS), Spring FilterRegistrationBean |
| C# | ASP.NET Core MVC, ASP.NET Core Minimal API, ASP.NET MVC, Carter, FastEndpoints, System.Net.HttpListener |
| C++ | Crow, Drogon, cpp-httplib, oat++ |
| Clojure | Compojure, Pedestal, Reitit, Ring |
| Crystal | Amber, Grip, HTTP::Server, Kemal, Lucky, Marten |
| Dart | Alfred, Angel3, Dart Frog, GetServer, Serverpod, Shelf, dart:io HttpServer |
| Elixir | Bandit, Phoenix, Plug |
| F# | Giraffe |
| Go | Beego, Chi, Connect-RPC, Echo, Fiber, Gin, GoFrame, Gorilla Mux, Goyave, Hertz, Huma, Iris, PocketBase, fasthttp, go-restful, go-zero, httprouter, net/http |
| Groovy | Grails |
| Haskell | Scotty, Servant, Yesod |
| Java | Apache Struts 2, Apache Wicket, Armeria, Dropwizard, JAX-RS, JDK HttpServer, JSP, Javalin, Micronaut, Play Framework, Quarkus, Spark Java, Spring, Vert.x |
| JavaScript | AdonisJS, Apollo Server, Astro, Elysia, Express, Fastify, Fresh, GraphQL Yoga, Hapi, Hono, Koa, NestJS, Next.js, Nitro, Node.js http/https, NuxtJS, Remix, Restify, SvelteKit |
| Kotlin | Ktor, Spring, http4k |
| Lua | Lapis, lor |
| PHP | CakePHP, CodeIgniter, Hyperf, Laminas, Laravel, Lumen, Mautic, Pure, Slim, Symfony, ThinkPHP, Yii2 |
| Perl | Catalyst, Dancer2, Mojolicious |
| Python | Bottle, Django, Falcon, FastAPI, Flask, Litestar, Pyramid, Quart, Robyn, Sanic, Starlette, Tornado, aiohttp, http.server |
| Ruby | Grape, Hanami, Rails, Roda, Sinatra, WEBrick |
| Rust | Actix Web, Axum, Gotham, Loco, Poem, RWF, Rocket, Salvo, Tide, Warp |
| Scala | Akka HTTP, Play Framework, Scalatra, Tapir, ZIO HTTP, http4s |
| Swift | Hummingbird, Kitura, Vapor |
| TypeScript | NestJS, TanStack Router, tRPC |
| Zig | Jetzig, Tokamak, Zap, httpz, std.http.Server |
iOS(
Info.plist自定义 scheme、universal links)与assetlinks.json/apple-app-site-association等服务端关联文件属于移动端面,见 mobile/index.md。
重点框架深入文档
对安卓、鸿蒙应用、鸿蒙 SA、Jalor 等框架的扫描机制、检测信号、端点模型与示例,见以下详细文档:
| 框架 | 文档 |
|---|---|
| Android(manifest + 路由注解) | mobile/android_routing.md |
| HarmonyOS 应用(deep link / 路由框架) | mobile/harmonyos.md |
| HarmonyOS SA(RPC 攻击面) | mobile/harmonyos_sa.md |
| Jalor(含 FilterRegistrationBean 规则) | java/jalor.md |
| ServiceComb / CSE | java/servicecomb.md |
| Apache CXF(JAX-WS / JAX-RS) | java/cxf.md |
移动端总览见 mobile/index.md,Java 企业框架总览见 java/index.md。
开发故事:TDD 驱动,70% 的开发量由测试承载
50+ 框架外加 4 个深度适配,质量怎么保证?先说难点:每个框架的路由写法、参数风格、边界 case 都不同;更怕的是改 A 框架时悄悄弄坏 B 框架 —— 没有测试网兜着,这种回归根本发现不了。
答案是 TDD。每个框架的适配都走同一条路径:
flowchart LR
Fixture["1. 编写真实 fixture<br/>迷你但语法真实的框架项目"] --> Red["2. 先写功能测试<br/>声明期望的端点清单(红)"]
Red --> Impl["3. 实现 Detector + Analyzer"]
Impl --> Green["4. 测试转绿"]
Green --> Manual["5. 真实项目人工验证<br/>收敛误报、补齐边界"]
测试先行不是口号,是制度:spec/AGENTS.md 规定 uncovered_test/ 目录为"测试先行 staging 区" —— 实现还没写完就先把测试放进去,转绿后才"转正"进 functional_test/。全库现有 1,046 个测试文件、688 个 fixture 项目,每个框架的提取能力都被测试锁定。
四个深度适配都是这么落地的:
| 适配对象 | 测试证据 | 故事点 |
|---|---|---|
| 鸿蒙 SA(System Ability RPC) | 3 个 fixture,一次声明 23 个期望端点 | "tracer bullet" 全流水线契约测试:证明 RPC method 能活着穿过优化器,不被强行归一成 GET |
| 鸿蒙应用(HAP) | 3 个 fixture,20 个期望端点 | module.json5 deep link / 系统路由表 / 6 种开源路由框架装饰器,全部先写期望再实现 |
| 安卓 | 11 个 fixture | 一套端点模型统一 manifest + App Links + 7 家路由框架(ARouter、WMRouter、DeepLinkDispatch、DRouter、ActivityRouter、ChenenyuRouter、XRouter) |
| 内部 Jalor 框架 | 13 个 fixture、12 个功能测试 | 失败测试先行的原生记录:"Before the fix, the analyzer emitted nothing" —— 先复现"什么都扫不出",再修到能扫出 |
70% / 30% 的开发节奏:解析、提取、参数映射这些约 70% 的开发量由 TDD 承载 —— 写 fixture、声明期望、实现到转绿;剩余约 30% 是人工验证与调整 —— 把工具对准真实大项目回归、收敛误报规则、补齐边界 case。
30% 的实战演练场:5 个鸿蒙 SA 开源项目
人工验证不是抽样看看,而是拿真实体量压。我们扫了 5 个 OpenHarmony 官方 SA 项目(bundlemanager 系列、security_access_token、window_manager):
| 维度 | 数字(2026-07-31 实测) |
|---|---|
| 代码规模 | 6,906 个源文件,约 86 万行 |
| 攻击面 | 1,330 个端点:1,292 个 RPC 方法(覆盖 65 个 SA 接口),另含 HTTP 与 CLI 入口 |
| 扫描耗时 | 约 28 秒 |
对照人工口径:梳理一个 SA 接口要定位 IDL 头文件 → ZIDL stub → 实现 → sa_profile 注册,熟手约 1~2 小时 / 接口,65 个接口就是 10 人日量级;裸用 LLM 则要面对 86 万行的切片喂入,以及 IDL ↔ stub 约定这个陌生领域。每一轮这样的真实项目回归,都会被固化回 fixture 和测试里 —— 测试网就是这么越织越密的。
为什么这对安全工具尤其重要:提取能力必须可重复验证。哪些框架已覆盖、哪些已实现未覆盖,公开记账(见 java/index.md 的 Test coverage 一节)。
工具的优势
| 优势 | 说明 |
|---|---|
| 实战验证 | 初代 URLScan(IDEA 插件)已前移接入流程 IT 流水线,累计支撑产品线揭示 3w+ 问题;URLScan CLI 全新重写,专为适配 AI 工具输入而设计。 |
| 不依赖运行环境 | 不需要把项目跑起来,直接扫源码;一次文件遍历、共享缓存,万级文件分钟级出结果,轻松应对 Java / Rust / Python / Go 大型混合项目。 |
| 能发现隐藏接口 | 没有被页面链接到、鉴权后才访问、测试环境才暴露的接口,也可能从源码里发现。 |
| 多语言多框架 | 50+ 主流框架、30+ 语言与平台;重点适配终端云业务(Android、HarmonyOS Deep Link、SA RPC、Jalor、ServiceComb),Web、移动端、配置文件、接口规格等入口来源通吃。 |
| 输出统一 | 不同语言和框架统一成 endpoint 清单,方便安全平台和 DAST 工具消费。 |
| 面向 AI 审计 | 输出统一 endpoint 清单,为下游 AI 工具提供完整输入,避免入口漏报;--ai-context 进一步聚合 guards / sinks / validators 上下文。 |
工具的局限
URLScan CLI 是静态分析工具,因此也有天然边界:
| 局限 | 说明 |
|---|---|
| 动态路由不一定完整 | 如果路径完全由运行时变量、数据库、远程配置生成,静态扫描可能无法还原。 |
| 可能有误报 | 测试代码、mock server、HTTP client 调用可能长得像路由,需要规则过滤。 |
| 不能证明接口真的在线 | 扫到的是代码或规格中的入口,不代表当前环境一定部署了它。 |
| 参数语义有限 | 能识别参数名和位置,但不一定知道业务含义、校验规则和权限逻辑。 |
| 新框架需要适配 | 未支持的框架需要新增 Detector 和 Analyzer。 |
所以它最适合作为:
攻击面发现的第一步,而不是漏洞结论本身。
而迈出第一步,只要 5 分钟。
5 分钟上手你的项目
插件党(推荐):
- VSCode 扩展市场搜索 URLScanCLI,点击安装(IntelliJ IDEA 用户:仓库内置插件见
intellij-plugin/,功能对齐); - 打开你的项目,点一下扫描;
- 浏览、筛选端点清单,点击任意端点直达源码行;需要时导出 JSON / Excel / Postman。
CLI 党:
urlscan -b . -f json
本文所有实测数字均标注日期与口径,欢迎直接引用 —— 更欢迎用你自己的项目复算一遍,那是最有说服力的验证方式。
License
MIT
urlscan-release
- 0
- 0
- 6
- 0
- 7
- about 1 month ago
- July 6, 2026
MIT License
Mon, 03 Aug 2026 01:02:03 GMT