当前位置:首页 > 热点

程序存在漏洞

2023年秋天,程序存漏我帮一个做跨境电商的程序存漏朋友查后台数据。他跟我说,程序存漏最近一周订单量掉了三成,程序存漏但流量没变。程序存漏我扫了一眼日志,程序存漏发现有个查询接口的程序存漏响应时间从平均80毫秒涨到了2.3秒。再往下翻,程序存漏一条SQL语句在循环里被调用了四千多次——典型的程序存漏N+1查询。代码是程序存漏两年前写的,当时商品表只有几百条记录,程序存漏跑起来没问题。程序存漏现在SKU涨到八万,程序存漏漏洞就炸了。程序存漏

这不是程序存漏什么高深的安全漏洞,没有注入,没有越权,就是逻辑上的疏忽。但它的破坏力一点不小。朋友那周损失了大概十二万销售额,还得连夜改代码、加缓存、重新压测。

我后来养成一个习惯:每次看到“当时没问题”的代码,都会多问一句——数据量涨十倍会怎样?并发翻三倍会怎样?这个假设帮我提前踩住了不少坑。去年另一个项目,用户上传头像的功能,前端做了尺寸校验,后端直接存原图。产品经理说“用户不会传太大的文件”。我查了上传日志,发现有人传过12MB的BMP。服务器磁盘三个月涨了40GB。后来加了后端压缩和格式白名单,磁盘增速才降下来。

程序漏洞分两种。一种是能被利用来干坏事的,比如SQL注入、XSS、越权访问。另一种是它自己就会坏掉,不需要攻击者,时间一到、数据一多、并发一高,自己就崩了。N+1查询属于后者,上传不限制也属于后者。这类漏洞更隐蔽,因为测试环境永远风平浪静。测试库那点数据,跑一年也碰不到边界。

有个做支付的朋友跟我讲过一件事。他们系统里有个对账任务,每天凌晨跑一次,把前一天的交易和银行流水比对。代码写得很规矩,循环里逐笔查询。上线半年没事。第七个月,某天交易量因为促销活动翻了六倍,对账任务跑了四个小时还没完。第二天早上运营发现前一天的账没对上,客服电话被打爆。他说那段时间最怕听到“定时任务又超时了”。

我自己的代码也出过类似的事。一个内部工具,用来批量给用户发通知邮件。我图省事,把用户列表一次性加载到内存里,循环发送。测试时用了五百个用户,两秒跑完。上线后运营导入了三万用户,内存直接爆了,进程被系统杀掉。那次之后我学会了分批处理,每批五百条,加个sleep,慢是慢点,但稳。

写代码的人容易有一种错觉:现在能跑,以后也能跑。但软件不是物理建筑,它活在变化的环境里。数据在涨,用户在涨,依赖的库在更新,服务器配置在调整。今天没问题的逻辑,明天可能就是定时炸弹。

怎么防?我的做法很土:每个循环里查数据库的地方,都标个TODO,问自己能不能改成批量查。每个接收用户输入的地方,都假设对方会传一个100MB的文件。每个定时任务,都估算一下数据量翻十倍后的执行时间。这些检查花不了几分钟,但能省掉半夜被叫起来修bug的麻烦。

漏洞不一定是别人攻进来的。很多时候,它只是静静躺在那里,等一个足够大的数字把它压垮。

分享到: