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()
