MySQL5.7-pymysql模块和SQL注入
Posted 花_城
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL5.7-pymysql模块和SQL注入相关的知识,希望对你有一定的参考价值。
系列文章目录
一、pymysql模块
-
作用:
该模块可以帮助我们使用python代码,操作数据库。
-
安装:
该模块是第三方模块,需要手动安装:
python3 -m pip install PyMySQL
-
语法:
# 导入模块 import pymysql # 建立与MySQL服务器的连接 conn = pymysql.connect(host='localhost', # MySQL服务器的主机地址 port=3306, # 端口号 user='root', # 用户名 password='123456', # 密码 database='task', # 目标数据库 charset='utf8mb4' # 编码,不要加“-”,否则报错 ) # 创建游标 # 游标是专门用于执行sql语句的 cursor = conn.cursor() # sql语句,不要忘记分号 sql = 'INSERT INTO user(name,age) values(%s,%s);' try: # 执行sql语句 cursor.execute(sql,('hugh',17)) # 提交对数据库的修改 conn.commit() except: # 执行回滚 conn.rollback()
- 第24行,
execute()
方法,第一个参数是要执行的SQL语句;第二个参数是SQL语句需要的值(在sql语句中用%s占位),采用元组形式传入。
其实,这里的SQL语句是字符串,我们完全可以采用格式化输出的方式直接修改,之所以这样大费周章的采用传参数的形式,是为了防止SQL注入。这个SQL注入会在下一节讲。
execute()
方法的返回值是SQL语句影响的记录行数。比如,插入了4行记录,就返回4。一般用不到这个返回值。 - 如果要一次插入多个值,就改用
executemany()
方法,传入的参数采用列表包含元组的形式:sql = 'INSERT INTO user(name,age) values(%s,%s)' cursor.executemany(sql,[('张三',11),('李四',21),('王五',31)])
- 第26行,在提交修改前,所有的修改操作都只是作用于内存当中临时的数据库,不是真正的数据库。一旦提交修改,才会应用到硬盘中保存的真正的数据库。
- 第30行,回滚用于SQL语句执行失败的时候,它会将撤销所有的修改操作,让数据库(不是真正的数据库,是内存当中临时的数据库)恢复到执行SQL语句之前的模样。
- 第24行,
-
获取SQL的执行结果:
这些方法通常只在查询操作中使用:# 获取sql的查询结果,返回值为元组类型 cursor.fetchone() # 获取一行记录 cursor.fetchmany(数量) # 获取指定数量的记录 cursor.fetchall() # 获取所有记录
-
返回值默认为元组类型,比如:
((1, 'hugh', 'male', 18), (2, 'tom', 'male', 33))
。 -
在创建游标时,向
cursor()
方法传入参数cursor=DictCursor
,可以使查询结果以字典形式返回,其中,键就是字段名:
[{'id': 1, 'name': 'hugh', 'gender': 'male', 'age': 18}, {'id': 2, 'name': 'tom', 'gender': 'male', 'age': 33},
。 -
游标取完第n条记录后,会向后移动到第n+1条记录的位置,下次再获取时,会从n+1条开始继续获取。
-
移动游标:
游标.scroll(偏移量, 模式)
偏移量代表移动的步数,正数代表向后移,负数代表向前移;
模式有两种:
相对位移——
relative
:从当前位置开始移动;绝对位移——
absolute
:从第一条记录的位置开始移动。
-
-
调用存储过程:
游标.callproc(存储过程名称, (存储过程的实参列表))
二、SQL注入及解决方法
永远不要信任用户的任何输入!
-
SQL注入的概念:
SQL注入是一种常见的网络攻击手法,它利用sql的语法特性和程序员编写程序时产生的漏洞,完成一些如跳过密码验证等的非法操作。
-
举例:
比如,在编写登录模块时,我们使用了如下查询语句来查询用户信息:
SELECT * FROM usrs WHERE username=用户输入的用户名 AND password=用户输入的密码;
并且,我们没有对用户的输入做任何处理,直接放到了SQL语句中。那么,当黑客输入了
xxx' OR 1=1 -- haacyugjavh
作为用户名时,原来的SQL语句就会变成下面的样子:SELECT * FROM usrs WHERE username='xxx' OR 1=1 -- haacyugjavh' AND password=;
username='xxx' OR 1=1
是一个恒成立的条件,所以无论输入什么用户名都会返回True;而--
后面的语句被当作注释忽略掉了,密码验证也被跳过。最终,黑客成功登录。 -
解决方法:
不要手动拼接sql语句,而是交给pymysql去处理。
先用
%s
占位:sql = 'SELECT * FROM usrs WHERE username=%s AND password=%s;'
再在执行sql语句时,以元组形式传入用户输入:
cursor.execute(sql,(username,password))
pymysql会自动处理用户输入,防止SQL注入。
以上是关于MySQL5.7-pymysql模块和SQL注入的主要内容,如果未能解决你的问题,请参考以下文章