Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
jshound — 从 Web 应用发布的 JavaScript 中找出它发出的每一个 API 请求:方法、URL、请求体、请求头和 GraphQL 操作。一条命令搞定。 | Kitploit
工具/GitHubGitHub/ambitsecurity/jshound
侦察静态分析漏洞分析信息收集Web安全渗透测试网络爬虫API 安全
GitHubambitsecurity/jshound

jshound

从 Web 应用发布的 JavaScript 中找出它发出的每一个 API 请求:方法、URL、请求体、请求头和 GraphQL 操作。一条命令搞定。

查看仓库
3274天前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

jshound

从 Web 应用发布的 JavaScript 中恢复该应用所构建的每一个请求:方法、URL、请求体、内容类型和请求头。

jshound 读取 supabase.com/dashboard:读入 2,282 个文件,输出 387 个请求,每个请求都带有其请求体

单页应用的 JavaScript 包中包含该应用能够发出的每一个 API 请求。给定一个 URL,jshound 会找到该应用的包,爬取其中的全部内容(包括懒加载的 chunk),并提取出这些请求。

它是被动的。它发出的唯一请求是用于获取公共静态文件、页面及其 JavaScript 的未认证 GET 请求。分析在本地运行,不会向应用的 API 发送任何内容。

安装

git clone https://github.com/AmbitSecurity/jshound && cd jshound
python3 -m venv .venv && source .venv/bin/activate
pip install -e .

需要 Python 3.10 或更高版本,以及 Node 18 或更高版本。

用法

jshound supabase.com/dashboard
$ jshound supabase.com/dashboard
  307    128B  https://supabase.com/dashboard
  200     19K  https://supabase.com/dashboard/org
  200     28K  https://frontend-assets.supabase.com/studio/8617532ae1a4/_next/static/chunks/1p849pzlxcp4n.js?dpl=dpl_ESaSquAbnWrJqbvvyRh7F1qj5wWH
  ...
supabase.com  200  2282 files (2281 from frontend-assets.supabase.com, 1 from supabase.com)  ->  387 endpoints
              1 declared chunk(s) could not be fetched
              -> .jshound/supabase.com/endpoints.txt  (also requests.jsonl, urls.txt, openapi.json)
  • 它获取了页面以及页面加载的每一个脚本,包括 frontend-assets.supabase.com 上的 2,281 个文件,supabase 的构建产物就位于那里。
  • 它发现了这些文件中懒加载的 chunk 和 import,获取了它们,并重复此过程,直到不再出现新文件。
  • 它读取了代码中的每一个请求,每行一个:
POST    https://api.supabase.com/platform/auth/{ref}/otp                                       {"phone":"state:phone"}
DELETE  https://api.supabase.com/v1/projects/{param_n}/functions/{param_e}
DELETE  https://supabase.com/dashboard/api/integrations/stripe-sync     application/json   {"projectRef":"input:e","startTime":"input:t"}
POST    https://supabase.com/docs/api/search/fts                        application/json   {"query":"computed:trim"}

一次处理多个目标,或从 stdin 读取列表:

jshound app.example.com api.example.com
cat scope.txt | jshound

磁盘上已有的文件,例如上一次运行留下的 js/ 文件夹,会在不访问网络的情况下被读取:

$ jshound examples/demo-app
GET    https://demo-app.test/api/feature-flags
POST   https://demo-app.test/t/events                                  {"sid":"?","evt":"?"}
DELETE https://demo-app.test/v1/sessions/current
POST   {baseUrl}/v1/media                         multipart/form-data  {"file":"file-upload"}
POST   {baseUrl}/v1/subscribe                     application/json     {"email":"computed:trim","pageUri":"state:href"}
GET    {baseUrl}/v1/users/{param_o}/profile

保存的内容

所有内容都会保存到 .jshound/<host>/,或保存到 -o DIR:

endpoints.txt上面的表格,每行一个请求
requests.jsonl每个请求一个 JSON 对象:method、url、body、content_type、headers、graphql 或 rpc,以及它来自的页面和文件
urls.txt对于主机已知的请求,输出 METHOD URL,供接受列表的工具使用
openapi.json一份 OpenAPI 3 文档,可导入 Burp、Caido 或 Postman
js/所有被获取的文件

阅读输出

  • {...} 是 jshound 无法解析的值,按代码中的写法输出:{baseUrl}、{window.__CONFIG__.apiBaseUrl}。在路径中,{ref} 是一个参数,{param_o} 是函数参数 o。
  • 没有主机的路径,例如 /api/surveys/,经过了 jshound 尚未追踪到其 base 的代码。requests.jsonl 会指明它来自哪个文件。
  • 请求体中的值会说明每个字段的值来自哪里:input: 一个参数,state: 对象的某个属性,computed: 某次调用的结果,? 未知。
  • application/json? 是根据该文件的其他请求推断出的内容类型,而非在调用处读取到的。~{...} 表示请求体中的字段比列出的更多。
  • {graphql} 是一个 GraphQL 操作,其名称、类型和变量作为请求体。

工作原理

收集、解析、追踪、写出:一个请求从配置模块出发,经过 axios 客户端,追踪到其调用处

支持的打包器

打包器懒加载 chunk URL模块树方式
webpack 5是是从语法树中读取 __webpack_require__.u
webpack 4是是没有 .u,因此按形状而非名称匹配具名 URL 构建器
Rspack是是与 webpack 兼容,通常输出 ESM
Turbopack是不适用完全没有构建器;chunk 列表是一个字面量数组
Vite / Rollup是不适用路径被直接写出(__vite__mapDeps);扁平的 ESM 没有可遍历的注册表
esbuild是不适用同上
Parcel是不适用运行时全局变量按构建带有后缀(parcelRequire5707),且 chunk 表是对象而非数组
Metro (React Native)不适用不适用只发布一个包,没有 chunk;通过 __METRO_GLOBAL_PREFIX__ 检测
webpack Module Federation是是构建器不携带 id 映射,因此 id 取自 __webpack_require__.e(480) 调用处

范围

jshound 会请求你给定的目标,以及该目标的页面所加载的 JavaScript 文件,无论它们托管在哪里。对于 supabase,这主要是 frontend-assets.supabase.com。这些是任何访问者的浏览器都会下载的公共静态文件。那些其他主机除了这些 GET 请求之外不会收到任何东西。

它会拒绝目标在私有地址空间(loopback、RFC1918、link local)中指定的任何 URL,除非你给定的目标本身就是私有的,或者你传入了 --allow-private。

选项

-o DIR结果保存位置(默认 .jshound/<host>)
-q不打印每个发出的请求
-v同时打印分析日志
--max-chunks N处理这么多懒加载 chunk 和 import 后停止(默认 50000)
--no-chunks不追踪懒加载 chunk
--proxy URL通过代理发送每个请求(或设置 JSHOUND_PROXY)
--proxy-ca FILE拦截 TLS 的代理的 CA 证书
--client PROFILE固定使用某一个浏览器 TLS 指纹,而不是在被封锁时轮换
--allow-private允许私有地址空间中的 URL(见“范围”)

局限性

  • 这些请求是从代码中读取的,而非经过测试。 一个请求可能存在于包中,却已从服务器上移除、被功能开关隐藏,或仅限管理员使用。jshound 告诉你客户端能发送什么,而不是服务器接受什么。
  • 仅在登录后才加载的代码不会被发现。 如果某个应用只在你登录后才下载其账单页面,那么未登录的 jshound 永远不会看到那段代码。
  • WAF 可能会封锁它。 如果第一个请求得到的是质询页面,例如 Cloudflare 的,运行会报告 blocked by Cloudflare 并且什么都读不到。jshound 会模仿 curl_cffi 所知道的最新 Chrome、Firefox 和 Safari,因此请保持 curl_cffi 为最新版本。--proxy 有助于应对速率限制和 IP 封禁,但对质询无济于事。
  • 运行时添加的脚本会被遗漏。 页面用 document.createElement("script") 插入的脚本,若其 URL 来自某次 API 调用,则不在 jshound 下载的任何内容之中。

贡献

参见 CONTRIBUTING.md。

许可证

MIT。

下载工具