2024年网安最新Web 安全漏洞 SSRF 简介及解决方案_httppost 修复ssrf漏洞

说到 Web 安全,我们前端可能接触较多的是 XSS 和 CSRF。工作原因,在所负责的内部服务中遭遇了SSRF 的困扰,在此记录一下学习过程及解决方案。SSRF(Server-Side Request Forgery),即服务端请求伪造,是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF 攻击的目标是从外网无法访问的内部系统。

SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定 URL 地址获取网页文本内容,加载指定地址的图片,下载等等。攻击者可根据程序流程,使用应用所在服务器发出攻击者想发出的 http 请求,利用该漏洞来探测生产网中的服务,可以将攻击者直接代理进内网中,可以让攻击者绕过网络访问控制,可以下载未授权的文件,可以直接访问内网,甚至能够获取服务器凭证。

笔者负责的内部 web 应用中有一个下载文件的接口 /download,其接受一个 url 参数,指向需要下载的文件地址,应用向该地址发起请求,下载文件至应用所在服务器,然后作后续处理。问题便来了,应用所在服务器在这里成了跳板机,攻击者利用这个接口相当于取得了内网权限,能够进行不少具有危害的操作。

SSRF 带来的危害有:

  • 可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的 banner 信息;
  • 攻击运行在内网或本地的应用程序(比如溢出);
  • 对内网 web 应用进行指纹识别,通过访问默认文件实现;
  • 攻击内外网的 web 应用,主要是使用 get 参数就可以实现的攻击(比如 struts2,sqli 等);
  • 利用 file 协议读取本地文件等。

通用的解决方案有:

  1. 过滤返回信息。验证远程服务器对请求的响应是比较容易的方法。如果 web 应用是去获取某一种类型的文件,那么在把返回结果展示给用户之前先验证返回的信息是否符合标准;
  2. 统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态;
  3. 限制请求的端口为 http 常用的端口,比如 80, 443, 8080, 8090;
  4. 白名单内网 ip。避免应用被用来获取获取内网数据,攻击内网;
  5. 禁用不需要的协议。仅仅允许 http 和 https 请求。可以防止类似于file:///,gopher://,ftp:// 等引起的问题。

由于笔者的应用 /download 接口请求的文件地址比较固定,因此采用了白名单 IP 的方式。当然,笔者也学习了一下更加全面的解决方案,下面给出安全部门同事的思路:

  1. 协议限制(默认允许协议为 HTTP、HTTPS)、30x跳转(默认不允许 30x 跳转)、统一错误信息(默认不统一,统一错误信息避免恶意攻击通过错误信息判断)

  2. IP地址判断:

    • 禁止访问 0.0.0.0/8,169.254.0.0/16,127.0.0.0/8 和 240.0.0.0/4 等保留网段
    • 若 IP 为 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 私有网段,请求该 IP 地址并判断响应 contents-type 是否为 application/json
  3. 解决 URL 获取器和 URL 解析器不一致的方法为:解析 URL 后去除 RFC3986 中 user、pass 并重新组合 URL

然后是按照以上思路实现的 Node.js 版本的处理 SSRF 漏洞的主要函数的代码:

const dns = require('dns')
const parse = require('url-parse')
const ip = require('ip')
const isReservedIp = require('martian-cidr').default

const protocolAndDomainRE = /^(?:https?:)?\/\/(\S+)$/

const localhostDomainRE = /^localhost[\:?\d]*(?:[^\:?\d]\S*)?$/
const nonLocalhostDomainRE = /^[^\s\.]+\.\S{2,}$/

/**
 * 检查链接是否合法
 * 仅支持 http/https 协议
 * @param {string} string
 * @returns {boolean}
 */
function isValidLink (string) {
    if (typeof string !== 'string') {
        return false
    }

    var match = string.match(protocolAndDomainRE)
    if (!match) {
        return false
    }

    var everythingAfterProtocol = match[1]
    if (!everythingAfterProtocol) {
        return false
    }

    if (localhostDomainRE.test(everythingAfterProtocol) ||
        nonLocalhostDomainRE.test(everythingAfterProtocol)) {
        return true
    }

    return false
}

/**
 * @param {string} uri
 * @return string
 * host 解析为 ip 地址
 * 处理 SSRF 绕过:URL 解析器和 URL 获取器之间的不一致性
 *
 */
async function filterIp(uri) {
    try {
        if (isValidLink(uri)) {
            const renwerurl = renewUrl(uri)
            const parseurl = parse(renwerurl)
            const host = await getHostByName(parseurl.host)
            const validataResult = isValidataIp(host)

            if(!validataResult) {
                return false
            } else {
                return renwerurl
            }
        } else {
            return false
        }
    } catch (e) {
        console.log(e)
    }
}

/**
 * 根据域名获取 IP 地址
 * @param {string} domain
 */
function getHostByName (domain) {
    return new Promise((resolve, reject) => {
        dns.lookup(domain, (err, address, family) => {
            if(err) {
                reject(err)
            }
            resolve(address)
        })
    })
}

/**
 * @param {string} host
 * @return {array} 包含 host、状态码
 *
 * 验证 host ip 是否合法
 * 返回值 array(host, value)
 * 禁止访问 0.0.0.0/8,169.254.0.0/16,127.0.0.0/8,240.0.0.0/4 保留网段
 * 若访问 10.0.0.0/8,172.16.0.0/12,192,168.0.0/16 私有网段,标记为 PrivIp 并返回
 */

function isValidataIp (host) {
    if ((ip.isV4Format(host) || ip.isV6Format(host)) && !isReservedIp(host)) {
        if (ip.isPrivate(host)) {
            return [host, 'PrivIp']
        } else {
            return [host, 'WebIp']
        }


### 一、网安学习成长路线图


网安所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/aa7be04dc8684d7ea43acc0151aebbf1.png)


### 二、网安视频合集


观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/f0aeee2eec7a48f4ad7d083932cb095d.png)


### 三、精品网安学习书籍


当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/078ea1d4cda342f496f9276a4cda5fcf.png)


### 四、网络安全源码合集+工具包


光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/e54c0bac8f3049928b488dc1e5080fc5.png)


### 五、网络安全面试题


最后就是大家最关心的网络安全面试题板块  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/15c1192cad414044b4dd41f3df44433d.png)![在这里插入图片描述](https://img-blog.csdnimg.cn/b07abbfab1fd4edc800d7db3eabb956e.png)  



**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以点击这里获取](https://bbs.csdn.net/topics/618540462)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值