Python-MySQL代码SQL注入问询:mysql.connector防护与其他利用方式
SQL注入漏洞分析与风险排查
代码背景
目标代码存在SQL注入风险,其中board_name为用户可控输入,table_name为内部不可控变量,代码实现如下:
def find_board_by_name(cls, connector, board_name, table_name: str): query = "SELECT * FROM {} WHERE name = '{}'".format(table_name,board_name.title()) print(query) try: connector.mycursor.execute(query) res = connector.mycursor.fetchone() if res: return res[1] return None except Exception as e: raise e
已尝试的注入测试
- 输入
board_name为:' OR '1'='1
测试成功,程序返回表中第一条数据(不符合预期,未提供有效名称却返回结果)。 - 输入
board_name为:';Delete Table BoardGames;
测试失败,报错:mysql.connector.errors.InterfaceError: Use multi=True when executing multiple statements。
核心问题
- 因代码未设置
multi=True,mysql.connector是否能防护大多数SQL注入? - 除上述两种方式外,还有哪些可利用该代码漏洞的方法?
解答
关于multi=True的防护作用
mysql.connector要求设置multi=True才能执行多语句查询,确实能阻止多语句注入(比如同时执行SELECT和DELETE),但这只是防护了一部分风险,绝不能认为能防护大多数SQL注入。单语句内的注入依然可以被利用,危害同样严重。
其他可利用的注入方式
以下是几种针对该代码的可行注入方法:
- 联合查询数据窃取:如果目标表和当前查询表的列数匹配,可通过联合查询获取其他表的数据。比如输入:
假设' UNION SELECT id, password FROM users--users表存在且列数匹配,就能直接获取用户密码字段的值。 - 布尔盲注:如果程序仅返回数据存在/不存在的布尔结果,可构造语句逐字符猜解数据。比如输入:
通过修改字符和位置,逐个获取目标数据。' AND SUBSTRING((SELECT password FROM users LIMIT 1),1,1) = 'a'-- - 时间盲注:如果程序无任何结果提示,可利用数据库延时函数判断注入是否生效,进而猜解数据。MySQL下输入:
若程序响应延迟5秒,说明注入语句被执行,可扩展猜解逻辑。' AND SLEEP(5)-- - 获取数据库元数据:查询数据库的表、列信息,为后续攻击铺路。比如输入:
能获取当前数据库下所有表和列的名称。' UNION SELECT table_name, column_name FROM information_schema.columns WHERE table_schema = DATABASE()-- - 单语句逻辑篡改:构造语句让原查询返回所有数据,或修改查询逻辑,比如输入:
用注释符' OR 1=1----截断后续语句,避免语法错误,直接返回全表数据。
总结
原代码的漏洞本质是直接拼接用户输入到SQL语句中,即使multi=True未开启,单语句注入依然能造成数据泄露、逻辑篡改等严重危害,必须使用参数化查询(connector.mycursor.execute(query, values))才能彻底修复。
内容的提问来源于stack exchange,提问作者digoalbuq2
相关产品推荐
相关产品推荐

