python入侵数据库数据库_python操作mysql数据库,以及注意sql注入

使用python操作mysql的逻辑如下图所示。基本过程为:1、开始;2、创建连接connection;3、创建并获取操作游标cursor;4、执行操作;5、关闭游标cursor;6、关闭连接; 7、结束。下面我们举一个简单例子s1python_mysql_sample.py 来实现向goods_cates表里插入两行数据:(0,'硬盘'),(0,'光盘')。

import pymysql # 1、导入pymsql模块

# connect对象用于建立连接

# host:mysql主机

# port: mysql端口默认3306

# database:数据库名称

# user: 用户名

# password: 密码

# charset: 通信编码

# 2、创建连接,设置连接ip,port,用户,密码,以及所要连接的数据库

conn = pymysql.connect(host='localhost', port=3306,database='jing_dong', user='root', password='hitzzy',

charset='utf8')

# cursor对象用于执行SQL语句

# 3、创建游标, 操作数据库, 指定游标返回内容为字典类型

cs1 = conn.cursor()

# 4、执行语句 execute(),返回受影响的行数结果。

count = cs1.execute('insert into goods_cates(name) values("硬盘")')

print(count)

count = cs1.execute('insert into goods_cates(name) values("光盘")')

print(count)

# 5、提交操作

conn.commit()

# 6、关闭游标和连接

cs1.close()

conn.close()

运行程序后,通过mysql终端查询语句查询goods_cates表,我们会发现,末尾已经添加了两行我们刚才添加的数据。

** (注意SQL注入)**

'''sql注入'''

import pymysql

def main():

find_name = input('请输入物品名称:') # 输入想要查询的物品名称

# print('select * from goods where name like %{}%' .format(find_name))

# 创建连接

conn = pymysql.connect(host='localhost', port=3306,database='jing_dong', user='root', password='hitzzy',

charset='utf8')

# 获取游标

cs1 = conn.cursor()

# 执行select语句,并返回受影响的行数:查询所有数据

# 安全模式

count = cs1.execute('select * from goods where name=%s', [find_name])

# 非安全模式

# 当find_name 被输入 " or 1 or " 包含双引号时,会显示表中所有数据,造成数据泄露。

# sql = 'select * from goods WHERE name="%s"' % find_name

# count = cs1.execute(sql)

print('查询到%d条数据:' % count)

# 获取并打印查询到的数据

for i in range(count):

# fetchone()执行查询语句时获取被影响的行的第一行

result = cs1.fetchone() # result 为一个元组哦

# print(type(result)) # 可以查看result的数据类型,加深理解

print(result)

# 关闭游标和连接

cs1.close()

conn.close()

if __name__ == '__main__':

main()

可以看到,当输入 x240 超极本,查询到此商品在库,并打印出该结果。

不要着急,我们把代码中安全模式的行注释掉,将非安全模式的行取消注释,然后再次输入 x240 超极本。我们也能查询到该商品信息。也就是说,execute里可以是一个SQL语句的字符串。那为什么还需要前面语法介绍的参数赋值呢?

再查询一种商品(“ or 1 or ”),再看看结果。奇怪,goods表中所有的数据都显示出来了。为什么呢?我们来分析一下。当把(“ or 1 or ”)赋值给find_name时,sql字符串变量的值为 select * from goods where name="“ or 1 or ”";大家看一下,where后的语句结果始终为True。所以会显示出goods表中所有数据,造成数据库数据泄露。因此在使用execute语句时,尽量使用安全模式中的参数化赋值,以避免因疏忽造成的SQL注入并引发安全问题。

sql注入中最常见的就是字符串拼接,研发人员对字符串拼接应该引起重视,不应忽略。

错误用法1:

sql= "select id, name from test where id=%d and name='%s'" %(id, name)

cursor.execute(sql)

错误用法2:

sql= "select id, name from test where id="+ str(id) +"and name='"+ name +"'"cursor.execute(sql)

正确用法1:

args=(id, name)

sql= "select id, name from test where id=%s and name=%s"cursor.execute(sql, args)

execute()函数本身有接受sql语句参数位的,可以通过python自身的函数处理sql注入问题。

正确用法2:

name=MySQLdb.escape_string(name)

sql= "select id, name from test where id=%d and name='%s'" %(id, name)

cursor.execute(sql)

python模块MySQLdb自带针对mysql的字符转义函数escape_string,可以对字符串转义。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值