加入收藏 | 设为首页 | 会员中心 | 我要投稿 均轻资讯网 (https://www.ijunqing.com/)- 云服务器、云原生、高性能计算、基础存储、数据迁移!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

PHP安全编码三大致命坑:90%开发者都踩过

发布时间:2026-10-21 08:19:29 所属栏目:PHP教程 来源:DaWei
导读:  一三年那会儿,我跟老陈在西直门那个没窗的隔间里改ThinkPHP模板,风扇嗡嗡响得像台拖拉机——现在想想,它转得比我们代码跑得还稳。他叼着烟,烟灰掉进键盘缝里,我俩谁都没擦。那时候接外包单子,甲方说“别让别人改了”,我

  一三年那会儿,我跟老陈在西直门那个没窗的隔间里改ThinkPHP模板,风扇嗡嗡响得像台拖拉机——现在想想,它转得比我们代码跑得还稳。他叼着烟,烟灰掉进键盘缝里,我俩谁都没擦。那时候接外包单子,甲方说“别让别人改了”,我们就把config.php写死数据库密码,再base64一遍,还觉得特安全。真蠢。不是后来出事才懂,是去年六月,客户系统被扫出三万条用户手机号,导出Excel时连带把脱敏逻辑也导进去了——那行substr($phone, 0, 3) . '' . substr($phone, -4) 居然直接塞进了SQL注入点的报错页面里。


  一七年……等等,到底是哪年?记不清了。反正那阵儿开始,备案突然卡住,好几个站上线拖了四十多天,客户天天问“为啥不能用”,我说“政策收紧”,其实心里慌得很——那会儿我们还在用PDO::prepare但不绑参,只bindParam,以为写了‘:id’就万事大吉。可参数值是从$_GET['id']直接拼进去的,中间连个intval()都懒得套。王磊当时还笑话我:“你写个is_numeric()都嫌手抖?”他后来自建了个CMS,全站用mysqli_real_escape_string,结果二二年他站被人拿sqlmap打穿了三张表,原因是他自己写的escape函数里忘了过滤backslash+null字节。我没笑他。我自己也在用。我原以为过滤掉单引号双引号就行,结果人家绕过mysql_client_encoding()设为gbk,一个%df%27就把我整懵了。


文章配图,仅供参考

  桌上那台戴尔显示器牌子我至今没记住,右下角贴着胶布补裂缝。一七年夏天特别热,空调不制冷,我们改完一处SQL注入,顺手把所有input框加了maxlength=32。天真。现在回头看,那不是加固,是贴创可贴治骨折。二二年做新项目,团队七个人,晨会第一句就是“XSS过滤走统一中间件还是前端React自带 sanitizer?”,没人提htmlspecialchars,更没人提magic_quotes_gpc——早废了,连文档都删干净了。可上周审计,我徒弟在Vue模板里用了v-html绑定用户昵称,还写了注释:“已用dompurify处理”。我盯了五分钟没说话。他不知道,我一三年写的那段防XSS正则:/]>/i,当年跑在IE6上,居然撑了四年没出事。


  老杨早不做站了,前年在朋友圈晒娃,照片背景是幼儿园滑梯,他配文“终于不用修php.ini里的disable_functions了”。我给他点了赞,没评论。其实我想说,二二年云WAF能拦住98%的RCE,但拦不住开发写file_put_contents($_POST['path'], $_POST['content']) 还开着debug=true——这事儿上周刚发生,在另一个团队。他们服务器没挂,只是日志里多了三千行“Warning: file_put_contents(): open_basedir restriction in effect”。我截图发过去,对方回了个OK。没道歉,也没改。无所谓。真无所谓。当年我们连open_basedir都不配设,现在人家敢设,已经是进步。


  一三年,SQL注入靠手写preg_replace过滤分号和union;一七年,我们信誓旦旦推自研WAF规则库,结果线上跑着MySQL5.1,客户端连接用的latin1,insert语句里藏个U+FFFD替代字符,绕过所有关键词检测;二二年,规则引擎都换成YARA了,可业务接口照样把token塞进HTTP Referer头,然后在error_log里明文打印出来——运维说“这是调试用”,我就笑笑,没提这事该归谁管。风扇还在响。那间屋子朝北,冬冷夏闷,但我记得特别清楚:一三年十二月十七号下午三点二十八分,客户电话来说后台进不去,我查了十分钟才发现,是有人把admin.php重命名成zadmin.php上传上去,又删了原文件——而我们的index.php里写了include_once 'admin.php';。就这行,我们留了一年半。


  我走错最狠那步,是一七年上线那个政务后台,要求等保三级。我带着三个人,硬是把所有输入输出都做过滤,却把session_id生成逻辑改成了md5(uniqid().rand()),还加了setcookie(‘sid’, $val, time()+3600, ‘/’, ‘.gov.cn’, true, true)。看上去很完美。可半个月后,渗透报告里写着:“Session固定可复现,利用条件:攻击者只需在任意.gov.cn子域种下恶意sid cookie,用户访问主站即劫持。”——我亲手写的domain=.gov.cn,让整个局域网的子站都成了跳板。那会儿我以为安全是加法,现在知道它是减法:砍掉每一个“看起来方便”的选项。包括那台戴尔显示器,包括老陈的烟,包括我当年写在便签纸上、贴在显示器边框上、写着“别忘关phpinfo()”的纸条。它早被撕掉了,没人记得什么时候撕的。


  最近开始学看Burp Suite的Flow图,画到一半发现,自己写的登录校验,居然把JWT decode后的payload直接放进session数组,再扔给前端展示。我盯着那个$session['user_info']['phone']愣了三分钟,想起一三年那个外包客户,他说“能不能让我后台看到用户手机号”,我说“能”,然后写了段echo $row['phone']。没脱敏。没判断权限。就那么裸着。现在这套我也拿不准还能干几年。

(编辑:均轻资讯网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!