1 什么是SQL注入?
用户提交带有恶意的数据与SQL语句进行字符串方式的拼接,从而影响了SQL语句的语义,最终产生数据泄露的现象
# 执行SQL语句,
sql = "select * from students where name='%s';" % "小明' or 1 or '"
print(sql) # select * from students where name='小明' or 1 or '';
cursor.execute(sql)
# 获取查询结果
ret = cursor.fetchall()
for row in ret:
print(row)
2 如何防止SQL注入?
解决方案: SQL语句参数化
- SQL语言中的参数使用%s来占位,此处不是python中的字符串格式化操作
- 将SQL语句中%s占位所需要的参数存在一个列表中,把参数列表传递给execute方法中第二个参数
啥都没查到# 准备SQL语句, %s是SQL语句的参数占位符, 防止注入
sql = "select * from students where name=%s;"
try:
# 执行SQL语句
cursor.execute(sql, ("小明' or 1 or '",))
# 获取查询结果
ret = cursor.fetchall()
for row in ret:
print(row)
# 查询时最好也commit, 不然用Navicat改了数据, 这里再查, 还显示之前的
db.commit()
except:
db.rollback()
3 多个参数防注入
# 准备SQL语句
sql = "insert students(name, age, gender) values(%s, %s, %s);"
try:
# 执行SQL语句
cursor.execute(sql, ("吴青峰", 35, "男"))
# (添加,删除,修改后)要提交修改到数据库
db.commit()
except:
# 对修改的数据进行撤销
db.rollback()
4 动态数据插入
data = {
'id': '1',
'name': 'zengsf',
'age': 20
}
table = 'students'
#获取到一个以键且为逗号分隔的字符串,返回一个字符串
keys = ', '.join(data.keys())
values = ', '.join(['%s'] * len(data))
sql = 'INSERT {table}({keys}) VALUES ({values})'.format(table=table, keys=keys, values=values)
try:
#这里的第二个参数传入的要是一个元组
if cursor.execute(sql, tuple(data.values())):
print('Successful')
db.commit()
except:
print('Failed')
db.rollback()
db.close()