宝塔 Nginx 免费防火墙 8.5 更新了什么?改了 6 个字母 s 和一行注释,漏洞一个没动

声明:本文为前作《宝塔 Nginx 免费防火墙 8.4/8.5 赶紧卸载吧:偷偷上传文件,凭据明文裸奔》的续篇。基于插件 8.4 与 8.5 官方全新安装包的真实逐字节 diff 结果撰写。
我知道 8.6 已经出了,但我这不是写得慢嘛,可以先预告一下:8.5→8.6 的修复方式也挺“幽默”的。
我那篇把“民国三年一场雨”(宝塔论坛内ID「宝塔技术-小强」)制作的 宝塔 Nginx 免费防火墙 8.4 扒了个底朝天之后,不少站长朋友留下了评论,说看完感觉太可怕了,连夜登录服务器把这玩意给卸载干净了。
本来以为这事告一段落,我也可以安心去搬我的砖了。
结果第二天下午,定时运维 agent 提示我测试机里的 宝塔 Nginx 免费防火墙 存在更新:
C. 主机「**」 → 「面板插件」-「宝塔 Nginx 免费防火墙」:存在更新[8.5],现有版本[8.4]。
说实话,看到这个消息时,我甚至在心底闪过一丝欣慰:可以啊!作者这响应挺迅速嘛!
不管之前代码写得多粗糙,只要看到社区反馈后,能连夜重构加固、把那些要命的 RCE 和免检后门堵上,那多少还算是个负责任的维护者,毕竟没要钱,这种被广泛使用的开源项目,我感觉维护者只要能力所能及地把大问题修了就行。
于是我兴冲冲地登录上测试服务器的宝塔面板,把 8.5 的最新安装包(free_waf.tar.gz)下载下来,解压,拉进本地仓库,跟上周那份被审计得千疮百孔的 8.4 源码执行一下diff命令:
git diff -w free_waf_8.4/ free_waf_8.5/
看着终端里的 diff 结果,我直接愣住了。
随后,我TM直接蚌埠住了,我决定收回刚才看到作者更新时的那丝欣慰。
这哪里是安全修复啊?这特么是一场足以载入中文开源史册的赛博行为艺术。
一、 逐字节比对:他到底“修复”了什么?
整个 8.5 版本,改动量小到一只手就能数得过来。
一万七千多行的工程文件,只动了 7 处。
1. 法学重大突破:只要代码里加了注释,偷用户就不算偷?
首先给大家欣赏一下本次 8.5 更新中最具黑色幽默气息的核心“修复”:
--- a/free_waf_main.py
+++ b/free_waf_main.py
@@ -304,6 +304,7 @@
+ # 云端查杀。需要上传到云端进行研判
def send_baota2(self, filename):
cloudUrl = 'https://www.bt.cn/api/panel/btwaf_submit'
pdata = {
是的,你没看错,他在那个未经用户允许、静默把整份 PHP 源码和服务器 IP 打包外传的函数上方,郑重其事地敲了一行中文注释:
# 云端查杀。需要上传到云端进行研判
我整个人都不知道该用什么表情了
不是,他这行注释是写给谁看的?!
- 是写给 Python 解释器看的吗?
- 是写给 Linux 操作系统看的吗?
- 是写给作者的良心看的吗?
- 还是说他觉得宝塔面板前端已经智能到,当用户点下宝塔 Nginx 免费防火墙里的「木马查杀」按钮的时候,屏幕上会凭空浮现出一行红色、高亮、闪烁、醒目的大字:“请注意,作者在 Python 源码第 304 行写了注释告知你,他会把你的文件直接送去云端服务器了?!
原本他的行为叫“隐蔽外传用户商业源码与敏感配置”;
加了这行注释之后,是不是在作者的逻辑宇宙里,这事能原地变得合情合理合法合规了?
“谁说我的 Nginx 免费防火墙偷偷摸摸静默传用户的源码了?那是你们没看代码啊!我第 304 行不是写了‘需要上传研判’吗?我都明确交代过了,是用户自己不看注释的,我告知用户了,绝对不是未经允许的静默上传行为!”
按照这个逻辑,入室行窃的小偷只要在撬棍上贴一张便签写着“入室研判,需将物品带回家里进行成色评估”,那在警察和法官面前就属于正常开展业务调研了对吧?!


- 首先,来,你是用户,你从面板上能看到的文字里,能看出来他会把你的文件主动静默地上传给宝塔的接口不?
- 他注释所在的位置:第一张图底下和第二张图里说的 WEBDIR+,指的是百度的免费 WebShell 扫描接口(
free_waf_main.py的 247-293 行) - 而负责把命中宽泛规则的代码自动偷偷上传给宝塔服务器的,是
free_waf_main.py的 142-160 行、304-338 行——两者是不相干的。
被发现存在静默上传后,他哪怕在前端界面加个复选框让用户自己选呢?哪怕改成行业通用的“只上传文件 SHA-256 哈希比对”呢?
诶,他不!他甚至懒得去动哪怕一行执行代码,硬生生在毫不相关的地方加了一行注释,就仿佛给自己念了一句免责咒语,这个偷偷上传用户文件、引起泄密的问题就被他“完美修复”了。
2. 传输安全拉满:从“裸奔偷”升级为“端到端加密偷”
剩下的 6 处修改,也是本次更新唯一的代码改动:作者把全局 6 处明文接口的 http://,批量替换成了 https://。
我哭死,作者他心里是有网络安全标准的!(虽然作者自己博客的证书都过期好久了)
- 在 8.4 时代:这套插件是用透明的塑料袋,装着你的全套业务源码、数据库密码、以及宝塔面板最核心的
userInfo.json(access_key和uid),在公网上明晃晃地裸奔; - 在 8.5 时代:作者大手一挥,贴心地给你换成了带 TLS 1.2/1.3 强加密、防中间人窃听、带防篡改校验的高级防窥加厚保险箱,体体面面、安安全全地把你的底裤送去宝塔的云端收藏呢!
中间人确实嗅探不到了,中间人直呼内行。
可问题是:你擅自偷偷把用户的核心数据未经授权打包送给其他人(主要是宝塔面板自己的)这个事实,变了吗?!
合着把你的银行卡和密码,从放在快递袋里寄给陌生人改成放到保险箱里寄给陌生人,它就不是寄给陌生人了吗?!

二、 那些被实锤的致命漏洞呢?这套免费 WAF 一个都没动!
上一篇文章里所有致命安全漏洞,在 8.5 里纹!丝!未!动!
我们来盘点一下那些在 8.5 里依然活蹦乱跳的“活化石”:
- POST 参数名免检(
continue_key):4.7.lua第 1668 行的逻辑一行没动。只要 POST 参数名叫kw、body、content,或者参数名长于 64 字节,WAF 依然当场眼瞎,SQL 注入和 XSS 载荷依然可以长驱直入。 -
算术验证码
?btwaf=nil秒破白送 1 小时通行证:4.7.lua第 573 行的tostring(vn3) == uri_request_args['btwaf']依然活着。判断前依然不检查vn3 ~= nil,黑客只要在 URL 后面带个?btwaf=nil,依然当场获取免检金牌。(这个倒是没默认启动,但是……既然这段逻辑完全没用,删一下花不了你几秒吧,起码比你打那段注释用的时间短吧) -
硬编码
hackcnm专属木马免杀白名单:free_waf_main.py第 136 行的pc = 'hackcnm'依然安详地躺在代码里。名字带hackcnm的木马依然享有这套防火墙的终身免检免死金牌。 -
本地管理路由
min_route零鉴权一键解封:4.7.lua第 1777 行依然只认remote_addr == '127.0.0.1'。本地的任何人依然能一键清空全网封禁 IP。 -
OpenResty 全局变量协程串号大乱炖:
4.7.lua里十几个核心上下文变量依然连个local都舍不得加,并发稍高依然在内存全局表里疯狂串号、跨请求覆盖。
哪怕……哪怕你顺手在验证码那儿加一行 if vn3 ~= nil then 呢?5 个单词的事情。
哪怕你顺手把那个侮辱智商的 hackcnm 给删了呢?敲两下 Delete 键的事情。
他不改。他连一个字符都懒得去碰。
从 8.4 到 8.5,版本号膨胀了整整 0.1,核心改动就 6 个字母加 15 个汉字。这已经不是“技术水平有限”能解释的了,只能说这是彻头彻尾的敷衍。
三、 总结:放下助人情结,尊重他人命运
在上周的文章发布前,我其实还在猜测:作者可能只是当年水平不足,东拼西凑改了改代码,自己并不清楚这些深层逻辑漏洞的危害。
但这个 8.5 版本,彻底击碎了我所有的幻想:
他不仅看懂了大家的反馈,他甚至知道大家在说他明文外传源码,所以他特地改了 HTTPS,还煞有介事地加了行注释解释了一下。但他压根就不在乎用户的安全死活,更不想花哪怕半小时去修修那些烂到骨子里的底层逻辑。 我不会说他做的不对,毕竟当下 WAF 业务确实不咋赚,更何况这是个免费的防火墙。
你的服务器安不安全并不重要,重要的是你挂着它,把它当个心理安慰剂,顺便把服务器的数据规规矩矩地供奉上去,来让厂商作为分析网络安全情况的数据。
话已至此,多说无益。要不要卸载,你们自己掂量。
PS:此文发布后,宝塔免费防火墙已经更新 8.6 了,我也分析了,只能说也很幽默,虽然扫描木马时确实不再上传用户文件了,但是修得也相当敷衍(未完待续……)

