mysql中防止sql注入
什么是sql注入
图片来源:百度百科
python 操作mysql产生sql注入问题
不用ORM框架,框架中已经集成了防范sql注入的功能,使用pymysql实践一下:
# 导入pymysql模块 import pymysql # 连接database conn = pymysql.connect(host='127.0.0.1', user='root',password='root',database='oss2_base_test',charset='utf8') # 得到一个可以执行SQL语句的光标对象 cursor = conn.cursor() # 定义要执行的SQL语句 proj_id = "146" sql = "SELECT * FROM oss2_base_test.auto_task where proj_id={};".format(proj_id) # 执行SQL语句 cursor.execute(sql) result = cursor.fetchall() print(result) # 关闭光标对象 cursor.close() # 关闭数据库连接 conn.close()
上面的sql最终被转为了:sql = "SELECT * FROM oss2_base_test.auto_task where proj_id='146';
符合预期,执行也是没有问题的
sql注入攻击:
sql = "SELECT * FROM oss2_base_test.auto_task where proj_id={};".format("'' or 1=1")
上面语句被转为:"SELECT * FROM oss2_base_test.auto_task where proj_id='' or 1=1;"
这将导致表中所有数据都被读取出来,造成的压力可想而知
我们如果涉及到只取部分数据,用limit限制,看sql注入攻击如何写:
正常查询:sql = "SELECT * FROM oss2_base_test.auto_task where proj_id={} limit 5;".format("146")
最终被转为:sql = "SELECT * FROM oss2_base_test.auto_task where proj_id='146' limit 5;"
sql注入:sql = "SELECT * FROM oss2_base_test.auto_task where proj_id={} limit 5;".format("'' or 1=1#")
最终转化为:sql = "SELECT * FROM oss2_base_test.auto_task where proj_id='' or 1=1 # limit 5;"
在sql中,#表示注释,#后面的语句都不会被执行,自然limit也就失效了,所有的数据都会被查出来
sql注入原理:
传入参数中'' or 1=1# 被当作sql语句执行了,or 后面 1=1使条件永远为真,且# 将limit进行注释,我们当前表就被脱裤了
预防:
不要手动进行拼接sql语句,execute() 提供了自动拼接功能,并进行了sql注入防范机制
替换为:
proj_id = "'' or 1=1 #"
sql = "SELECT * FROM oss2_base_test.auto_task where proj_id=%s limit 5;"
cursor.execute(sql,(proj_id,))