MySQL动态SQL必须用PREPAREEXECUTE配合?占位符绑定数据值表名列名等标识符须白名单校验用户变量传参需显式赋值避免作用域与类型陷阱权限和性能开销需专项优化。MySQL存储过程里CONCAT拼接SQL就是高危操作直接用CONCAT把用户输入塞进动态SQL里等于把钥匙交给攻击者。哪怕加了TRIM或REPLACE也拦不住 OR 11 -- 这类绕过——因为字符串拼接发生在SQL解析前预处理机制根本没机会介入。常见错误现象SET sql CONCAT(SELECT * FROM users WHERE name , in_name, );传入in_name admin OR 11就完蛋。必须改用PREPARE EXECUTE配合占位符?让MySQL服务端做参数绑定所有用户可控的值包括表名、列名、排序字段都不能走?——它们不属于“数据参数”得用白名单校验CONCAT兜底EXECUTE stmt USING var1, var2;里的var1必须是用户态变量不能是存储过程参数直接代入否则仍可能被污染哪些地方能用?占位符哪些绝对不能?只对**数据值**有效MySQL明确不支持用它代替标识符表名、列名、数据库名。试图写SELECT * FROM ?会报错ERROR 1064 (42000)。使用场景分两类安全可用WHERE条件值、INSERT的VALUES、UPDATE的SET右侧表达式如UPDATE t SET col ? WHERE id ?必须拦截表名FROM ?、列名ORDER BY ?、函数名SELECT ?(col)、LIMIT偏移量LIMIT ?, ?中第一个?合法第二个不行替代方案对标识符做严格白名单检查比如IF in_table NOT IN (users, orders) THEN SIGNAL SQLSTATE 45000 SET MESSAGE_TEXT Invalid table; END IF;USING子句传参时变量生命周期和类型陷阱执行EXECUTE stmt USING a, b;前a和b必须已存在且有值。存储过程参数in_name不能直接出现在USING里——MySQL会报ERROR 1318 (42000)。容易踩的坑 橙篇 百度文库发布的一款综合性AI创作工具