SQL注入(execute()之下)

在用pymysql模块操作验证注册登陆的时候,涉及字符串拼接时容易出现明明账户密码不对的情况sql语句还是可以被执行,这样就导致用户可以绕开账户密码就能进入数据库。废话不说,看图:
SQL注入(execute()之下)
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

换另一种‘错误’的账号看结果:
SQL注入(execute()之下)
上面’账户‘至少mcc还是正确的,再来一个’完全不沾边‘的账户
SQL注入(execute()之下)
原因是什么呢?

根本原因在于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

SQL注入(execute()之下)

上一篇:Mysql Utilities


下一篇:c#中Lamdba匿名函数查询语句