PHP Web安全实战:SQL注入防护精要
|
2026年5月,我接手了一个被黑客攻击的PHP电商系统——用户下单时,订单表被注入恶意SQL,导致所有商品价格被改为1元。修复时发现,原开发团队直接拼接用户输入的`$product_id`到SQL语句:`$sql = "SELECT FROM products WHERE id = ".$_GET['id'];`。这种写法,连菜鸟黑客都能用Burp Suite轻松突破。 新技术里,PHP 8.3的`PDO::prepare()`配合命名参数绑定,是防注入的硬核方案。我测过,用`$stmt = $pdo->prepare("SELECT FROM products WHERE id = :id"); $stmt->execute(['id' => $_GET['id']]);`,哪怕输入是`1; DROP TABLE users--`,PDO也会自动转义为字符串,数据库只会收到`'1; DROP TABLE users--'`,根本不会执行恶意代码。这比老旧的`mysql_real_escape_string()`靠谱多了——后者在字符集混乱时仍可能被绕过,比如GBK编码下,`%bf%27`会被转义成`%bf%5c%27`,但`%bf`在GBK里是有效汉字开头,可能和后续字符组成攻击向量。 去年我参与的一个金融项目,安全团队强制要求所有SQL必须用预处理。有次测试,前端传的`$account`参数是`123' OR 1=1--`,用拼接写法会返回所有账户数据;但用预处理后,数据库只查`account = '123' OR 1=1--'`的记录——由于`account`字段是字符串类型,`OR 1=1`被当作普通字符,查询结果为空,攻击失败。这案例说明,预处理不仅防注入,还能强制类型检查,比手动转义更彻底。 但新技术也有坑。上个月我帮朋友修复一个CMS,他用了Laravel的Eloquent ORM,以为能自动防注入。结果发现,他在`whereRaw()`里直接拼接了用户输入:`Model::whereRaw("name LIKE '%{$name}%'")->get();`——这和直接拼接SQL没区别!Eloquent的`where()`方法会自动用预处理,但`whereRaw()`是直接执行原始SQL,必须手动用`?`占位符或`bindValue()`绑定参数。这细节,很多教程都没提过。
文章配图,仅供参考 我主观判断:PHP防注入,预处理是唯一可靠方案,但得用对地方——PDO的预处理、Eloquent的`where()`、Doctrine的DQL,这些官方推荐的方式才安全。那些“轻量级ORM”或“自定义查询构建器”,如果底层还是拼接SQL,用起来和裸写没区别。2026年5月那次攻击,如果原团队用了预处理,根本不会发生。下一步该干啥?去检查你的代码库,搜`->query(`、`mysql_query(`、`sprintf(`这些函数——但凡拼接SQL的,都是定时炸弹。如果项目老到只能用PHP 5.x,至少用`mysqli_real_escape_string()`,但别指望它100%安全——字符集、魔法引号关闭、多语句执行这些变量,都可能让转义失效。新技术虽好,用不对照样白搭。 (编辑:开发网_新乡站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


PHP工程师跨界创业:技术整合实战手册
Go赋能安全运维:技术融合重塑站长防护新视野
Go视角下的跨界融合:PHP工程师的技术新启迪
浙公网安备 33038102330465号