什么是 SSRF 和 CSRF?
更新: 11/16/2024 字数: 0 字 时长: 0 分钟
前两天在公司内部发布了一个服务,他的主要功能是前端分析Charles所抓包的请求信息,在后端再次执行一次该请求。
之所以开发这个服务是因为测试的时候需要替换cookie再次调用接口,每次使用Postman非常麻烦,索性抓取流量后,直接在后端再执行一次。之所以不在前端执行,是因为公司的服务接入了CSRF,会校验Origin和Refer,浏览器是无法伪造的。
然而今天收到了公司安全部门的警告,判断这个服务中重新运行接口的这个功能存在高危漏洞,可能存在SSRF攻击。
之前听说过CSRF,可是SSRF是什么鬼,百度了一下才知道了相关内容。
CSRF(Cross-site request forgery)
CSRF,中文名:跨站请求伪造。简单理解就是高危程序伪造请求会访问你的后端,进而盗取用户信息。
上面的解释可能还是有些抽象,举一个我碰见的具体例子。
之前开发了一款B站的Chrome插件,可以自动签到,获取硬币,还可以直播每日签到等等功能。如果需要实现这些功能就需要调用B站的接口。抓取了相关的接口信息就需要执行,chrome插件的后台进程可以看做一个单独的网页,他的域名为chrome://xxxxx
(xxx为具体的插件id)。最开始的时候在chrome后台进程获取到了b站的cookie,同时加入了b站所校验的安全参数,然后执行,不出所料,b站返回了错误。(图是用postman构造的)
但是最开始复制的curl在postman是可以成功执行的。抓取了接口内容发现了请求header中origin
和referer
被自动填入了chrome插件后台的域名,浏览器防止伪造这才触发了错误。origin
用于指明当前请求来自于哪个站点,referfer
表示从哪个页面链接过来的。
origin
和referer
判断是最基本的CSRF校验,为了防止CORS(跨域资源共享),并且一般的浏览器都会防止伪造。
然而如何抵御CSRF的攻击呢?
只对origin
和referer
做判断并不能完全防止CSRF,postman就可以轻易伪造请求,自己写的服务也是可以达到相同的内容。以b站举例,他会在query和cookie中添加一些校验参数,但是攻击者通过分析也可以找到这些校验参数。即使这些参数设置了生效时间也是无济于事。我的插件最后也是正常在浏览器跑了起来,可见只是这些校验并不足以防止恶意攻击。
最好的方法就是后端做防御,比如记录短时间内的访问次数,或者通过分析攻击者的流量模型来判断你的请求是否正常等。
SSRF(Server-Side Request Forgery)
中文名:服务器端请求伪造,是一种由攻击者构造,由服务端发起请求的一个网络攻击,一般用来在外网探测或攻击内网服务,其影响效果根据服务器用的函数不同,从而造成不同的影响。
SSRF 形成的原因大都是由于服务端提供了从其他服务器获取数据的功能且没有对目标地址做过滤与限制。比如从指定URL地址获取网页文本内容,加载指定地址的图片,下载等等。
上面的介绍摘自百度,刚看理解起来还是有些困难,就拿这次触发SSRF的情况来举例。
触发漏洞的接口是通过向后端传入请求参数,后端执行,然后返回内容。乍一看没什么问题,但是细想一下漏洞是非常严重的。他的大致代码如下:
c.Bind(req)
resp, err := http.Get(req.Url)
str := ioutil.ReadAll(resp.Body)
c.JSON(200, string(str))
如果这时,你不对传入的url做限制,外网访问这个接口,里面携带了内网的url,由于服务是部署在内网中,他可以访问到内网,这时就可以通过外网访问到内网的资源。攻击者通过遍历就可以获取多个内网数据,同时还有可能监听端口,从而有针对性的攻击内网。在php中,有些方法甚至可以同时支持http和file协议,还可以访问到你的服务器上的文件。
为了防止SSRF,最好的办法就是对url做判断,防止其访问到内网资源。