sql注入与防止SQL注入之参数化处理
sql注入的两种情况:
操作代码:
import pymysql user = input('用户名: ').strip() pwd = input('密码: ').strip() # 链接 conn = pymysql.connect(host='localhost', user='root', password='123', database='db1', charset='utf8') # 游标 cursor = conn.cursor() # 执行完毕返回的结果集默认以元组显示 # cursor=conn.cursor(cursor=pymysql.cursors.DictCursor) # 执行sql语句 sql = 'select * from t1 where name="%s" and pwd="%s"' % (user, pwd) # 注意%s需要加引号 print(sql) res = cursor.execute(sql) # 执行sql语句,返回sql查询成功的记录数目 print(res) cursor.close() conn.close() if res: print('登录成功') else: print('登录失败')
正常情况
用户名: zj 密码: 123 select * from t1 where name="zj" and pwd="123" 1 登录成功
sql注入
1、sql注入之:用户存在,绕过密码
用户名: zj" -- saaa 密码: a select * from t1 where name="zj" -- saaa" and pwd="a" 1 登录成功
2、sql注入之:用户不存在,绕过用户与密码
用户名: 12e" or 1=1 -- asddas 密码: select * from t1 where name="12e" or 1=1 -- asddas" and pwd="" 1 登录成功
防止SQL注入之参数化处理
优化后的代码
import pymysql user = input('用户名: ').strip() pwd = input('密码: ').strip() # 打开数据库连接 conn = pymysql.connect(host='localhost', user='root', password='123', database='db1', charset='utf8') # 创建一个游标对象 cursor = conn.cursor() # 参数化处理 sql = "select * from t1 where name=%s and pwd=%s" # 注意%s需要去掉引号,因为pymysql会自动为我们加上 print(sql) res = cursor.execute(sql, [user, pwd]) # 执行sql语句,返回sql查询成功的记录数目 print("res:", res) # 关闭游标 cursor.close() # 关闭数据库 conn.close() if res: print('登录成功') else: print('登录失败')
正确输入
用户名: zj 密码: 123 select * from t1 where name=%s and pwd=%s res: 1 登录成功
sql注入,失败示例
用户名: zj" -- sad 密码: a select * from t1 where name=%s and pwd=%s res: 0 登录失败