Server-Side Request Forgery,服务端请求伪造;是一种由攻击者构造形成由服务端发起请求的一个安全漏洞;
一般情况下,SSRF 攻击的目标是从外网无法访问的内部系统。
- 内网服务中会遇到 SSRF,应用所在服务器成了跳板机,
- 攻击者利用这个接口相当于取得了内网权限,能够进行不少具有危害的操作
SSRF参考 https://juejin.cn/post/6844903765145993224
https://www.npmjs.com/package/egg-security
yarn add egg-security
exports.security = {
csrf: {
type: 'ctoken', // can be ctoken, referer, all or any, default to ctoken
// if useSession set to true, the secret will keep in session instead of cookie
useSession: false,
ignoreJSON: false, // skip check JSON requests if ignoreJSON set to true
cookieName: 'csrfToken', // csrf token's cookie name
sessionName: 'csrfToken', // csrf token's session name
headerName: 'x-csrf-token', // request csrf token's name in header
bodyName: '_csrf', // request csrf token's name in body
queryName: '_csrf', // request csrf token's name in query
refererWhiteList: [], // referer white list
},
domainWhiteList: ['http://localhost:4200']
}
safeRequest.js
const urllib = require('urllib')
const ipUtil = require('ip')
// IP 黑名单
const ipBlackList = [
"10.0.0.0/8",
"127.0.0.1/8",
]
module.exports = async function (url='', options={}) {
if (!url) throw new Error('请求的URL,为必填项')
const params = {
...options,
checkAddress: address => {
for (const ip of ipBlackList) {
if (ipUtil.cidrSubnet(ip).contains(address)) return false
}
return true
}
}
return urllib.request(url, params)
}
SSRF解决方案
解决SSRF基本思路:识别危险的跳转链接,例如
- 内网域名
- IP
- 直接获取 URL对应的IP,域名则返回对应的 IP;在对IP进行判断是否为内网IP,即可防御 SSRF内网探测
- 白名单内网 ip
- 免应用被用来获取获取内网数据,攻击内网
- 短连接网站
- 过滤返回信息
- 验证远程服务器对请求的响应是比较容易的方法
- 如果 web 应用是去获取某一种类型的文件,那么在把返回结果展示给用户之前先验证返回的信息是否符合标准;
- 统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态;
- 限制请求的端口为 http 常用的端口,比如 80, 443, 8080, 8090;
- 禁用不需要的协议。仅仅允许 http 和 https 请求。可以防止类似于file:///,gopher://,ftp:// 等引起的问题
SSRF的出现场景
- 装修类,例如,店铺装修
- 代理类
- 在线爬虫类
- 测速类
SSRF的危害
- 可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的 banner 信息;
- 攻击运行在内网或本地的应用程序(比如溢出);
- 对内网 web 应用进行指纹识别,通过访问默认文件实现;
- 攻击内外网的 web 应用,主要是使用 get 参数就可以实现的攻击(比如 struts2,sqli 等);
- 利用 file 协议读取本地文件等