C0oki3s/ssrf
GitHub: C0oki3s/ssrf
一个基于 Node.js 的 SSRF 请求防护模块,通过黑名单、白名单与 CIDR 规则阻止对内网资源的非法访问。
Stars: 1 | Forks: 0
## ssrf
[][download-url]

## 服务器端请求伪造(SSRF)
攻击者可以利用服务器上的功能来读取或更新内部资源。攻击者可以提供一个或修改一个 URL,服务器上的代码会读取或提交数据到该 URL,通过精心选择的 URL,攻击者可能能够读取服务器配置(如 AWS 元数据)、连接到内部服务(如启用的 HTTP 数据库)或向内部服务发送 POST 请求,而这些服务本不应被暴露 [阅读更多](https://owasp.org/www-community/attacks/Server_Side_Request_Forgery)
## 安装
`npm install ssrf`
## 用法
```
// Back-compat usage (direct API)
ssrf.options({
blacklist: "/ssrf/list.txt", // Linux; on Windows use 'C:\\Users\\host.txt'
path: false
})
const gotssrf = await ssrf.url("http://13.54.97.2")
```
## ssrf.url()
ssrf.url 返回 Promise,因此请在 try-catch 块中使用 `await ssrf.url("http://example.com")`
```
try{
const result = await ssrf.url(url)
//do stuff if success
}catch{
//do stuff if fail
}
```
### ssrf.options({})
options 接受两个参数
+ blacklist
+ path
#### blacklist
blacklist 参数接受指向文本文件的绝对路径输入
示例:
- /usr/list/blacklist.txt (Linux)
- C:\\Users\\host.txt (Windows)
默认情况下没有黑名单,但如果用户传递了绝对路径,则会读取文件并在每次命中中间件时运行一个 for 循环
##### 文件格式
```
evil.com
example.com
87.26.7.9
98.72.6.2
```
#### path
path 参数接受一个布尔值(true 或 false)
默认值为 True,这意味着它将返回 /path 和附加到 Host 的 ?parameters
示例:如果用户发送 `http://example.com/path1?param=1`,则返回 `http://example.com/path1?param=1`
##### True
返回绝对 URL `http://example.com/path1?param=1`
##### False
返回主机名 `http://example.com 或 http://www.example.com`
该模块防止来自保留字符 `@` 的攻击和 DNS 重新绑定攻击。要了解更多关于 DNS 重新绑定的信息,请参阅 [更多](https://github.com/C0oki3s/research/tree/main/DNS-Rebinding)
## 高级配置(CIDR、白名单、IP 输入)
该库现在支持使用主机名、IP 和 CIDR 范围设置允许/拒绝列表,来源可以是文件或数组,并接受原始 IP/主机输入。
示例:
```
const path = require('path')
const ssrf = require('ssrf')
ssrf.options({
// Load lists from files (one entry per line; supports host/IP/CIDR; lines starting with # are comments)
blacklistFile: path.join(__dirname, 'blacklist.txt'),
whitelistFile: path.join(__dirname, 'whitelist.txt'),
// Or configure directly
blacklistHosts: ['evil.com'],
blacklistIPs: ['13.54.97.2'],
blacklistCIDRs: ['10.0.0.0/8', 'fd00::/8'],
whitelistHosts: ['api.example.com'],
whitelistIPs: ['203.0.113.10'],
whitelistCIDRs: ['203.0.113.0/24', '2001:db8::/32'],
// Return only scheme+host when false (defaults to true for full URL)
path: false
})
// Inputs can be full URLs, hostnames, or raw IPs
await ssrf.url('http://api.example.com/v1?q=1') // allowed if matches whitelist
await ssrf.url('evil.com') // throws if blacklisted
await ssrf.url('13.54.97.2') // throws if blacklisted or not whitelisted
```
说明:
- 仅允许 `http` 和 `https` 方案。
- 输入可以是完整 URL、主机名、原始 IPv4 或原始 IPv6。原始 IPv6 会规范化为括号形式(例如 `::1` -> `http://[::1]`)。
- 主机名会解析为所有 A/AAAA 记录,并对每个地址进行评估。
- 默认情况下会阻止私有、循环、链路本地、多播和保留 IP,除非明确通过 IP 或 CIDR 白名单。
- 如果提供了白名单,则目标必须匹配白名单;否则即使不在黑名单中也会被拒绝。
- IPv4 私有地址在以十六进制、八进制或单整数形式提供时也会被检测(例如 `0x7f000001`、`0177.0.0.1`、`2130706433`)。
## Express 中间件
全局使用(整个应用):
```
const express = require('express')
const ssrf = require('ssrf')
const app = express()
app.use(express.json())
app.use(
ssrf.middleware(
{
// Lists from files or arrays
// blacklistFile: 'C:\\lists\\deny.txt',
whitelistHosts: ['api.example.com'],
whitelistCIDRs: ['2001:db8::/32', '203.0.113.0/24'],
blacklistCIDRs: ['10.0.0.0/8', 'fc00::/7'],
path: false
},
{
source: 'body', // 'body' | 'query' | 'params' | 'headers'
key: 'url', // field name in the chosen source
attachKey: 'safeUrl', // attach approved URL to req.safeUrl
replaceOriginal: false,
blockOnError: true, // respond with 400 + JSON by default
statusCode: 400,
// onError: (errors, req, res, next) => { ...custom handler... }
}
)
)
app.post('/fetch', (req, res) => {
res.json({ ok: true, safeUrl: req.safeUrl })
})
```
在端点级别使用(路由特定配置)并使用隔离实例:
```
const filesOnly = ssrf.create({
whitelistHosts: ['files.example.com'],
path: true
})
app.post('/upload', filesOnly.middleware({ source: 'query', key: 'target' }), (req, res) => {
res.json({ ok: true, url: req.safeUrl })
})
```
直接使用隔离实例(无全局状态):
```
const instance = ssrf.create({ path: false })
try {
const safe = await instance.url('example.com')
// use safe
} catch (e) {
// e.message contains a JSON array of reasons
}
```
## 示例
- 完整的 Express 示例:`examples/express-server/server.js`
- 应用级中间件:`app.use(ssrf.middleware(...))`
- 路由级中间件(带隔离实例):`const inst = ssrf.create(...); app.post('/path', inst.middleware(...))`
## TypeScript
此包提供类型定义。在 TypeScript 项目中正常导入即可获得 options 和 middleware 的智能感知:
```
import ssrf = require('ssrf')
const inst = ssrf.create({ path: false, whitelistCIDRs: ['2001:db8::/32'] })
const safe = await inst.url('example.com')
```
标签:GNU通用公共许可证, IP 黑名单, MITM代理, Node.js, NPM 模块, SSRF, Streamlit, URL 过滤, 中间件, 反绕过, 后端开发, 安全防护, 服务器端请求伪造, 漏洞防护, 私有 IP 过滤, 网络安全, 访问控制, 路径处理, 隐私保护