存储过程是否防SQL注入?如何在存储过程中使用参数化查询
你的存储过程无法防范SQL注入,正确的参数化实现方式看这里
为什么当前存储过程存在注入风险
你现在的存储过程通过concat把用户参数直接拼进SQL字符串,完全没做参数化处理。比如如果param1传入' OR 1=1 --,拼接后的SQL会变成:
select * from TABLE1 WHERE column1 = SOME_VALUE AND COLUMN2 like '%' OR 1=1 --%'
这会直接绕过原有查询条件,返回所有数据,属于典型的SQL注入漏洞。
存储过程里如何实现参数化查询
核心逻辑是不要将用户参数直接拼接进SQL语句,改用占位符,再通过绑定参数的方式执行查询。以下是针对你场景的修改方案:
修改后的存储过程代码
CREATE PROCEDURE `PROCEDURE_NAME`(PARAM1 VARCHAR(500), PARAM2 VARCHAR(500), PARAM3 VARCHAR(500)) BEGIN -- 初始化基础查询,仅保留固定条件 SET @query = 'SELECT * FROM TABLE1 WHERE column1 = SOME_VALUE'; SET @param_count = 0; -- 动态添加查询条件,仅拼接占位符而非参数值 IF PARAM1 IS NOT NULL THEN SET @query = CONCAT(@query, ' AND COLUMN2 LIKE ?'); SET @param_count = @param_count + 1; SET @param1 = CONCAT('%', PARAM1, '%'); END IF; IF PARAM2 IS NOT NULL THEN SET @query = CONCAT(@query, ' AND COLUMN3 LIKE ?'); SET @param_count = @param_count + 1; SET @param2 = CONCAT('%', PARAM2, '%'); END IF; IF PARAM3 IS NOT NULL THEN SET @query = CONCAT(@query, ' AND COLUMN4 LIKE ?'); SET @param_count = @param_count + 1; SET @param3 = CONCAT('%', PARAM3, '%'); END IF; -- 预处理语句并根据参数数量绑定对应值 PREPARE st FROM @query; CASE @param_count WHEN 1 THEN EXECUTE st USING @param1; WHEN 2 THEN EXECUTE st USING @param1, @param2; WHEN 3 THEN EXECUTE st USING @param1, @param2, @param3; ELSE EXECUTE st; END CASE; DEALLOCATE PREPARE st; END
关键改动说明
- 用
?作为SQL中的参数占位符,避免直接拼接用户输入 - 将模糊查询的
%拼接在参数值上,而非SQL语句中 - 通过
EXECUTE ... USING绑定参数,数据库会自动完成参数转义,彻底阻断注入路径
Python端调用注意事项
你当前的Python代码:
param1 = request.get('param1') param2 = request.get('param2') param3 = request.get('param3') pymysql.callproc('PROCEDURE_NAME', (param1, param2, param3))
本身是合规的,callproc方法会自动处理参数的参数化传递,只要存储过程内部实现正确,整个调用链路就不会存在注入风险。
内容的提问来源于stack exchange,提问作者jackysatpal
相关产品推荐
相关产品推荐

