0x00
吃了好几天瓜,今天放松一下,讲讲SSRF漏洞原理吧~尽量讲得简单一点(本来这个漏洞产生的原因也不复杂),如果有上代码的必要,每段也不超过10行(伪代码),以弄清楚主要逻辑为主。会通过攻击方与防守方两个角度来说明(左右互博)~
0x01
SSRF(服务端请求伪造)
其实很简单,一句话描述就是:我们可以通过暴露在公网上的某个网站或者应用程序,去访问我们原本访问不到的地址。
其中的核心要点就是,我们可以控制服务器访问我们指定的地址,其实就相当于将它当成了一个代理服务器使用了,通过它来绕过了内网访问限制。
0x02
那为什么会产生这样的漏洞?我们以实际业务场景举个栗子:
假设我们有一个在线翻译网页的功能,比如用户输入一个英文网址,我们处理后,返回一段HTML(翻译之后的网页内容)。
那服务端的代码可能是这么实现的(够不够简单!):
# url为需要翻译的目标网址,通过前端传入
def http_request(url):
# 请求这个网址,获取原内容
text = http.request(url)
try:
# 翻译原内容
translated_text = translate(text)
# 返回翻译后的数据
return translated_text
except Exception as e:
# 如果出现了异常,就返回原网址内容
return text
是不是很简单地实现?不过功能是实现了,但是安全方面是一点也不考虑啊!这不就是一个天然的代理服务器?利用这个功能可以请求内网/外网/本地任意地址,并且还可以回显内容!
不需要任何绕过操作,攻击者可以直接通过http协议打内网,或者file协议获取敏感文件等等~
这时候有点安全意识的程序员就会考虑怎么去防御SSRF攻击了。那我只允许你访问我让你访问的内容不就行了(朕不给的,你不能抢)?直接协议限制 + 白名单过滤:
# url为需要翻译的目标网址,通过前端传入
def http_request(url):
# 如果目标地址不是http协议
if url is not http:
return '别搞了,小老弟'
for domain in domain_white_list:
# url是否包含白名单域名
if domain in url:
return '域名不在白名单内,走开!'
text = http.request(url)
...
看起来好像不错?起码有点安全意识了,但是不多。这里我要对开发们提点建议了,对于域名白名单这种限制,千万千万千万不要使用这种字符串包含判断的方式!!一绕一个准:
http://evil.com?a=whitedomain.com
但如果我现在是白帽:开发佬们,打份工嗟,需求实现了不就行啦,考虑这么多容易秃头~
应该先提取域名,再进行全匹配:
# 提取域名
url_domain = extra_domain(url)
for domain in domain_white_list:
# url是否包含白名单域名
if domain == url_domain:
return '域名不在白名单内,走开!'
...
到这里基本上就差不多了,但是为了避免某些基础组件出现问题(没错,我说的就是它[SSRF绕过域名白名单的一种方式——CVE-2024-24806(影响大量nodejs服务)]),从而被绕过白名单,我们还可以增加一个对返回值进行过滤,直接避免回显,可以极大的降低危害:
def http_request(url):
...
translated_text = translate(text)
# 对返回数据做过滤,有敏感信息直接脱敏或不返回
return filter_result(translated_text)
到这里,这个功能基本上就可以很大概率上避免SSRF攻击啦,但是从攻击者的角度来看的话,只要其中任意一步没有实现好,那都是潜在的目标。
留个彩蛋,对于SSRF防御,还有一个很重要的点在于服务端在请求目标地址时,需要禁止重定向请求,有师傅知道为什么吗?知道原因也就知道另一个潜在的绕过手段。
0x03
总的来说,SSRF大概就是这么产生的,然后防御方式来来回回也就这么回事,理论上来说只要开发真正的理解SSRF攻击,是完全可以写好防御代码的,而且非常简单!但是现实从来不和你讲理,毕竟SSRF在OWASP Top10
上从17年的榜上无名到21年修正后的第10名,深刻的说明了是人就会犯错这个道理。
最后总结一些可能会出现SSRF的业务场景:
-
API接口,比如这种:victom.com/rest?api=api.com&method=xxxx
-
分享功能,比如这种:victom.com/share?url=victom.com/page
-
在线网页翻译,比如这种:victom.com/translate=xxxx.com
-
图片、视频转码/审核等
遇到上面这样的场景,师傅们可以尝试考虑一下SSRF。今天就到这啦,文章难写(还是吃瓜简单#),希望大家有所收获~
欢迎关注我的公众号“混入安全圈的程序猿”,更多原创技术文章第一时间推送