cur.execute("SELECT id,title FROM goods WHERE nick = %s", (nick,))
# 不要写成 "... WHERE nick = '" + nick + "'"

用户把昵称改成 O'Neil,商品列表接口立刻回 500,日志里是 near "Neil": syntax error,错误 SQL 原文里昵称被双引号包着拼进去了。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。

追下去是这么回事:字符串拼接把用户输入当成 SQL 语法的一部分,一个单引号就让语句提前闭合。后面剩下的字符被解析成别名或运算符,语法树直接崩掉。这条接口能报错还算走运,不报错的时候就是注入点。

围绕「SQL 拼接单引号」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。监控和日志的时间要对上,时区不一致会多绕很大一圈。

处理上按这个顺序:把拼接语句改成占位符 参数从第二个参数传进去;检查所有 LIKE 和 IN 的动态部分 占位符不能写在引号里;排序字段拼不进占位符 用白名单映射 不要直接接字符串;给这条接口补一个带单引号的用例 每次发版跑一遍。

确认没问题再收工,昵称填 O'Neil 接口返回 200 列表正常 SQL 日志里是 %s 占位符。

作者 9823189