当前位置: 当前位置:首页 > 百科 > sql注入单引号被转义正文

sql注入单引号被转义

作者:百科 来源:百科 浏览: 【大 中 小】 发布时间:2026-10-17 06:12:07 评论数:

开发三年,入单我见过最冤的引号义SQL注入防御,就是被转把单引号全部转义成`\'`,然后拍着胸脯说“我们防住了”。入单

某次代码审计,引号义对方系统用户登录框,被转后端逻辑是入单`$username = str_replace("'", "\\'", $_POST['username']);`,再拼进SQL。引号义看着挺安全?被转我输入`admin\' or 1=1 -- `,结果直接登进去了。入单为什么?引号义因为转义发生在PHP层,但数据库用的被转GBK编码。`%bf%5c`在GBK里是入单个合法汉字,转义符`\`被吞了,引号义单引号反而成了“自由人”。被转这叫宽字节注入,转义函数在它面前就是个纸糊的盾。

更常见的坑是数字型参数。很多人只转义字符串,却忘了`id`这种数字。你传`id=1 and 1=2`,根本不经过单引号,转义函数连看都不看。我见过一个后台删除接口,`$_GET['id']`直接拼SQL,连intval都没加。测试时输入`1 or sleep(3)`,数据库真就卡了三秒——这种漏洞比单引号注入更隐蔽,因为代码里根本没出现引号。

还有种情况,转义本身没问题,但位置错了。比如你写了`addslashes`,可SQL语句里用了`LIKE '%$keyword%'`。用户输入`%\' or 1=1 -- `,转义后变成`%\\' or 1=1 -- `,看着没问题。但MySQL的`LIKE`语法里,反斜杠是转义通配符的,`\\'`会被解析成`\'`,然后单引号又出来了。这种逻辑漏洞,光靠转义函数根本防不住。

别误会,我不是说转义完全没用。它至少能挡住90%的脚本小子。但真正的攻击者不会硬碰单引号,他们会找编码差异、找数字参数、找二次注入——把恶意代码先存进数据库,再在另一个页面拼进SQL。这时候转义早被拆了,数据是“干净”的,但拼出来就是注入。

我自己的习惯是:能用参数化查询绝不用拼接,能用ORM绝不用原生SQL。转义只是最后一道兜底,不是防线。有一次接手老项目,几百条SQL全是拼接,我花了三天全改成PDO预处理。改完再测,之前能绕过的注入全废了。那种感觉,比转义函数给我带来的安全感实在多了。

所以单引号被转义,从来不是问题的终点。它只是把一个低级错误升级成了中级错误——攻击者换个姿势,照样捅穿。真正的防御是改变查询方式,而不是跟特殊字符玩猫鼠游戏。你转义单引号,他给你上宽字节;你加intval,他给你堆叠查询。这场仗,永远在动态博弈,但唯一靠谱的,是别把用户输入当SQL代码的一部分。