在用pymysql模块操作验证注册登陆的时候,涉及字符串拼接时容易出现明明账户密码不对的情况sql语句还是可以被执行,这样就导致用户可以绕开账户密码就能进入数据库。废话不说,看图:
sql代码为:
user = input('账户:').strip()
pwd = input('密码:').strip()
sql = 'select * from register where name = "%s" and pwd ="%s"' %(user,pwd)
res = cursor.execute(sql)
if res == 1:
print('登陆成功')
print(cursor.fetchall())
else:
print('登陆失败')
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
换另一种‘错误’的账号看结果:
上面’账户‘至少mcc还是正确的,再来一个’完全不沾边‘的账户
原因是什么呢?
根本原因在于mysql的注释语法 – ,上面的两张图显示了两种sql注入情况,第一种是用户存在,绕过密码,第二种情况用户不存在,绕过用户与密码
看一下第一种情况的sql语句:
select * from register where name = "mcc" -- sdadadf" and pwd =""
- 1
- 2
数据库中,-- 后的所有内容都被注释掉,即使再输入密码也是没用的,最后的sql语句是select * from register where name = “mcc”,这句sql语句可以被正确执行,也能查出mcc的结果
select * from register where name = "xxx" or 1=1 -- saddjna" and pwd =""
- 1
在数据库中,-- 后面的条件全部被注释掉,where 的过滤条件就剩name=“xxx” or 1=1,1=1显然永远成立,where的最终过滤条件就是True,sql执行的就是select * from register 。
解决方法
原来是我们对sql进行字符串拼接
sql=‘select * from register where name="%s" and password="%s"’ %(user,pwd)
res=cursor.execute(sql)
#改写为(execute帮我们做字符串拼接,我们无需且一定不能再为%s加引号了)
sql="select * from register where name=%s and password=%s"
- 1
#!!!注意%s需要去掉引号,因为pymysql会自动为我们加上res=cursor.execute(sql,[user,pwd])
#pymysql模块自动帮我们解决sql注入的问题,只要我们按照pymysql的规矩来。
copy自:https://blog.csdn.net/Bobdragery/article/details/90273880