PHP安全编码三大致命坑:16年工程师血泪总结
|
上季度末,凌晨两点十七分,机房空调坏了第三天,嗡嗡嗡震得人太阳穴跳——我蹲在IDC走廊啃冷掉的葱油饼,饼渣掉在工牌挂绳上,一粒没掸。老张端着泡面路过,勺子刮碗底刮出刺啦声,说:“你那个PHP补丁,先别上线。”我说行,他转身又补一句:“运营那边催第四轮了。”我没接话,因为刚看见监控里PHP-FPM子进程又开始吃内存,像有谁往池子里倒了整瓶蜂蜜,黏糊糊拉丝。 第一个坑:filter_input()当防弹衣穿。三个月前查那个支付回调漏洞,前端传的订单号是base64_decode($_GET['order']),后端没做任何校验就拼进SQL。我原以为他们至少会用mysqli_real_escape_string()兜一下底——结果呢?整个模块压根没开PDO预处理,连占位符都写成字符串拼接。我翻日志看到攻击者在回调URL里塞了‘order=ZmFrZV9vcmRlciI7IERST1AgVEFCTEUgYWN0aXZpdHk7’这种玩意儿,解出来就是“fake_order"; DROP TABLE activity;”。当时我正把笔记本支在快递纸箱上,左手按住键盘右下角防止它滑下去,右手攥着半截没点着的烟,没点——忘了打火机在抽屉第二格最里面,跟三年前丢的SIM卡针混在一起。
文章配图,仅供参考 第二个坑:unserialize()接外部数据跟裸奔差不多。去年双十一前一天,运维小王半夜打电话来喊我,说订单页白屏率突然飙到十八秒(不是百分比,是真真正正加载十八秒)。我连VPN进去看trace,发现是某个活动组件调用了一个叫get_user_cache()的函数,里面反序列化了Redis里存的用户偏好JSON,但Redis key被上游改成了“user:pref:{$_GET['uid']}”,而uid字段根本没过滤——攻击者把uid设成“123|O:8:\\"stdClass\\":1:{s:4:\\"code\\";s:7:\\"phpinfo\\";}”,直接让phpinfo()在生产环境弹窗。老杨——就是被兼容性折磨了六年前端的老杨——那天下午还在群里吐槽IE11里flex-wrap失效,我回他“你先别管wrap,先把phpinfo关了”,他回了个捂脸哭的表情,后面跟了句“你咋知道我电脑开着phpinfo”。我没理,因为我正盯着屏幕右下角时间,三点零四分,窗外开始下雨,雨点砸在机柜玻璃门上,嗒、嗒、嗒,不连贯。第三个坑:file_get_contents()读URL不加allow_url_fopen=false还敢标“已加固”?这事儿最气人——不是它多难修,是它修完一周后又被新同事绕过去。那人刚转PHP不到五个月,写了段逻辑:$url = 'https://api.xxx.com/check?token=' . $_COOKIE['auth']; $res = json_decode(file_get_contents($url)); 我看到的时候,手已经悬在键盘上了,准备敲php.ini路径,结果桌上的外卖盒突然被人碰倒,辣子鸡丁撒在《深入PHP源码》第217页,油印出来一块深褐色。我拿纸巾擦,擦到一半停了——书页背面用铅笔画了个歪歪扭扭的箭头,写着“这个hook可以绕过disable_functions”,字迹是老张的。我敢打包票是他写的,因为那支铅笔削得太尖,笔芯断过三次,本子边缘还留着两道刮痕。 其实这些坑本身不新鲜,二十年前就有人踩过。但每次重构都说“这次一定搞干净”,结果上线前五分钟,测试妹子举着手机跑过来问:“老师,为啥扫码登录后跳转地址里多了一串base64?”,我说你截个图,她晃手机太猛,解锁键被误触三次,最后那张截图底下带了条微信通知弹窗,显示“【技术中心】下周三全员复盘SLO指标”,我把截图放大看了三遍,确认URL里那段base64解出来是“/admin/reset_password.php?id=1&submit=1”,但没说话——不是不想说,是听见隔壁工位阿哲接电话,声音忽大忽小:“……对,就那个CMS插件,不用管SQL注入,他们只扫XSS……” 优胜劣汰这词不是我说的,是审计报告第一页盖红章的地方写的。但它站得住,不是因为代码多漂亮,是因为踩坑的人一批批走,留下的人只剩两条路:要么抄文档一行行核对disable_functions列表,要么学会在error_log里闻出sql_mode变更的味道。上礼拜我改完那个filter_input漏判的分支,在测试环境跑了三遍,第四遍时忽然想起,我们从来不管$_SERVER['HTTP_REFERER']有没有被篡改过——这事儿我原以为早该归安全组管,结果去钉钉找他们,弹出一条系统提示:“该群已解散,最近一次消息发送于二〇二一年八月。” 现在桌上还摆着那盒没吃完的辣子鸡丁,冷透了,表面结了层薄油膜。我打算等下给架构组发个邮件,标题写“关于统一禁用unserialize与file_get_contents远程调用的建议”,正文第一句删了七次,最后一次写的是:“这事真没必要再议了。” (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


BAT资深Web前端工程师总结:未来5年前端发展四大趋势前瞻