顾乔芝士网

持续更新的前后端开发技术栈

“SQL注入即服务”:一个10年历史系统的奇幻演变

大家好,这里是 架构资源栈 !点击上方关注,添加“ 星标 ”,一起学习大厂前沿架构!

关注、发送 C1 即可获取 JetBrains 全家桶激活工具和码!

在程序员的世界里,总会遇到一些“前人种树”的系统,留下来的代码让人摸不着头脑,仿佛是上个世纪某位不愿透露姓名的程序员半夜梦游时敲下的产物。

小 D 最近就遇到了这么一个项目:一个全球数百万设备日志的分析系统。看似正经,实则离谱。一开始你以为它只是个普通报表工具,点点按钮选个时间范围,结果打开之后,发现这玩意儿竟然是个—— “SQL 注入即服务”系统(SQL Injection as a Service,简称 SIAAS)

报表入口只有一个输入框?!

没错,在这个系统的“最新版本”中,开发者取消了所有按钮、下拉框、日期选择器,只留下了一个纯净的文本框:自己写 SQL 吧,哥!

这个页面几乎毫无防护,整个数据库就这样赤裸裸 #技术分享地暴露在用户面前。你想查啥?写 SQL!你想删库?也没人拦你!这种设计让人怀疑开发者是不是搞错了职业跑去做黑客工具平台了。

但当小 D 翻开 Git 版本控制的历史,一切变得有迹可循。这套系统,其实是经过了10年的“逐步进化”,一步一步从规范走向失控的。

一切的开始:只是“加个字段”而已

最初,系统还是一个中规中矩的报表页面,有日期范围、有关键词输入,有个“生成”按钮——再正常不过。

第一个需求是“加一个字段”。开发者非常配合,直接在 SQL 语句里加了个字段,前端也更新了,皆大欢喜。

结果没多久,又有人说要加一个来自别的表的字段。于是开发者加了 JOIN 语句,但新问题来了:有些数据看不到了,有人抱怨 VLOOKUP 出错了,还有人嫌字段顺序乱了……最终达成一致:新字段必须放在表格最后 ,即使它跟“创建时间”关系密切也不能靠前。

报表越来越多,逻辑越来越绕

后来,开发团队加了个报表类型的下拉框。听起来不错,但这意味着:每次业务有新需求,就要加一个新的报表模板。

两份报表、五份报表、十份报表……最终膨胀到了几十个。而且由于命名混乱、字段顺序微调等问题,很多报表其实差不多,但名字完全看不懂。

于是,开发者又“进化”了一下:把报表名字存进数据库里 ,这样用户可以自己改名。谁曾想,有人直接把报表名改成了空字符串,前端整个炸了。

最后只能祭出“管理员才能改名”的限制。

SQL 神秘页面上线:“SQL自由查询入口”

某天,一个有“感染力”的员工提出:能不能加个隐藏页面,大家自己写 SQL 查询更自由?

开发者居然答应了——上线了一个内部可见的“超级管理员页面”,左侧还有预置的常用 SQL,点击即执行,简直就是 SQL playground。

“保护措施”:只屏蔽关键词

当然也不是完全裸奔,后来有人加了个粗暴的防护逻辑:只要检测到 SQL 中含有 INSERTUPDATECREATE ,直接返回 401 拒绝访问。

这说明什么?说明有人已经在偷偷修改数据了……

随着这个“安全机制”的上线,原来的报表页面也彻底被替换成了这个万能的 SQL 编辑器页面。

慢查询、卡死、LIMIT机制上线

灾难才刚刚开始。有人写了个复杂的 JOIN 语句,查询执行30秒还没出结果,系统快被拖死。

于是紧急加了个查询超时设置:最开始是30秒,然后迅速变成了30分钟……很快,开发者又想出“LIMIT”策略:查询语句末尾强制追加 LIMIT ,不写就自动加。

后来更细了:必须出现在 最后一个分号前 ,不然视为非法。

页面上也开始贴出各种“友情提示”:

  • 不要在凌晨备份时间跑查询
  • 不会JOIN就别乱JOIN
  • 请写LIMIT,拜托了

最后,这个系统落到了我手里……

当小 D 加入团队时,这个奇葩系统正式归自己维护。

原本打算大改一波,重新做个正常报表组件:日期范围、筛选框、输入框……但看完源码和十年来的 JIRA 工单后,小 D 放弃了。

直到某天,一个员工执行了一个 DELETE 命令——以为只删了一条数据,结果系统整体报表全部异常。原来两个表之间没有外键,JOIN 逻辑全靠“日期字段相等”。

INNER JOIN table2 t2 ON
    DATE(t1.entry_date) = DATE(t2.entry_date)

小 D 只能临时加了一条“假数据”补回去,然后顺便把 DELETE 加入黑名单。

系统总算活过来了。

尾声:我没能拯救它,但我被它“拯救”了

本以为能慢慢改进这套系统,让它走上正轨。但现实往往不是理想主义者的朋友。

午饭回来没多久,两个安全部同事走到小 D 工位,和气但坚定地说:

“我们要送你离开这栋大楼。”

至于后续是裁员还是系统真的闯了大祸,就请参考《 当机器把我开除了 》这篇后续故事吧。


小结

这个故事其实揭示了很多老系统常见的“演变病”:

  • 每一个看似“临时改动”,最后都成了永久设计;
  • 开发者在“响应需求”中逐渐迷失初心;
  • 最终系统演变为不可控状态,却没人敢动它。

技术债最怕的不是没还,而是不断加注变成“技术 P2P” 。这个 SQL 注入即服务的案例,真是活生生的“黑暗教程”。


本文由博客一文多发平台 OpenWrite 发布!

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言