学习电脑,计算机系统故障维护,电脑技术,电脑知识学习-就上第二电脑网
当前位置: 首页 > 网络编程 > python

python2进制 高位补0Python中操作mysql的pymysql模块详解

 更新时间: 2019-07-06 11:29:30   作者:第二电脑网   来源:第二电脑网   浏览数:2105   我要评论

pymsql是Pytho中操作MySQL的模块,其使用方法和MySQLdb几乎相同。但目前pymysql支持pytho3.x而后者不支持3.x版本。 本文测试pytho版本:2.7.11。mysql版本:5.6.24 一、

三、关于pymysql防注入

 1、字符串拼接查询,造成注入

正常查询语句:

#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import pymysql

conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1')
cursor = conn.cursor()
user="u1"
passwd="u1pass"
#正常构造语句的情况
sql="select user,pass from tb7 where user='%s' and pass='%s'" % (user,passwd)
#sql=select user,pass from tb7 where user='u1' and pass='u1pass'
row_count=cursor.execute(sql) row_1 = cursor.fetchone()
print row_count,row_1

connmit()
cursor.close()
conn.close()

构造注入语句:

#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import pymysql

conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1')
cursor = conn.cursor()

user="u1' or '1'-- "
passwd="u1pass"
sql="select user,pass from tb7 where user='%s' and pass='%s'" % (user,passwd)

#拼接语句被构造成下面这样,永真条件,此时就注入成功了。因此要避免这种情况需使用pymysql提供的参数化查询。
#select user,pass from tb7 where user='u1' or '1'-- ' and pass='u1pass'

row_count=cursor.execute(sql)
row_1 = cursor.fetchone()
print row_count,row_1


connmit()
cursor.close()
conn.close()

 

 2、避免注入,使用pymysql提供的参数化语句

正常参数化查询

#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"

import pymysql

conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1')
cursor = conn.cursor()
user="u1"
passwd="u1pass"
#执行参数化查询
row_count=cursor.execute("select user,pass from tb7 where user=%s and pass=%s",(user,passwd))
row_1 = cursor.fetchone()
print row_count,row_1

connmit()
cursor.close()
conn.close()

构造注入,参数化查询注入失败。

#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import pymysql

conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1')
cursor = conn.cursor()

user="u1' or '1'-- "
passwd="u1pass"
#执行参数化查询
row_count=cursor.execute("select user,pass from tb7 where user=%s and pass=%s",(user,passwd))
#内部执行参数化生成的SQL语句,对特殊字符进行了加转义,避免注入语句生成。
# sql=cursor.mogrify("select user,pass from tb7 where user=%s and pass=%s",(user,passwd))
# print sql
#select user,pass from tb7 where user='u1' or '1'-- ' and pass='u1pass'被转义的语句。

row_1 = cursor.fetchone()
print row_count,row_1

connmit()
cursor.close()
conn.close()

结论:excute执行SQL语句的时候,必须使用参数化的方式,否则必然产生SQL注入漏洞。

3、使用存mysql储过程动态执行SQL防注入

使用MYSQL存储过程自动提供防注入,动态传入SQL到存储过程执行语句。

delimiter 
DROP PROCEDURE IF EXISTS proc_sql 
CREATE PROCEDURE proc_sql (
  in nid1 INT,
  in nid2 INT,
  in callsql VARCHAR(255)
  )
BEGIN
  set @nid1 = nid1;
  set @nid2 = nid2;
  set @callsql = callsql;
    PREPARE myprod FROM @callsql;
--   PREPARE prod FROM 'select * from tb2 where nid>? and nid<?';  传入的值为字符串,?为占位符
--   用@p1,和@p2填充占位符
    EXECUTE myprod USING @nid1,@nid2;
  DEALLOCATE prepare myprod;

END
delimiter ;
set @nid1=12;
set @nid2=15;
set @callsql = 'select * from tb7 where nid>? and nid<?';
CALL proc_sql(@nid1,@nid2,@callsql)

pymsql中调用

#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import pymysql

conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1')
cursor = conn.cursor()
mysql="select * from tb7 where nid>? and nid<?"
cursor.callproc('proc_sql', args=(11, 15, mysql))

rows = cursor.fetchall()
print rows #((12, 'u1', 'u1pass', 11111), (13, 'u2', 'u2pass', 22222), (14, 'u3', 'u3pass', 11113))
connmit()
cursor.close()
conn.close()

四、使用with简化连接过程

每次都连接关闭很麻烦,使用上下文管理,简化连接过程

#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"

import pymysql
import contextlib
#定义上下文管理器,连接后自动关闭连接
@contextlib.contextmanager
def mysql(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1',charset='utf8'):
  conn = pymysql.connect(host=host, port=port, user=user, passwd=passwd, db=db, charset=charset)
  cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
  try:
    yield cursor
  finally:
    connmit()
    cursor.close()
    conn.close()

# 执行sql
with mysql() as cursor:
  print(cursor)
  row_count = cursor.execute("select * from tb7")
  row_1 = cursor.fetchone()
  print row_count, row_1

更多:python2进制 高位补0Python中操作mysql的pymysql模块详解
https://www.002pc.comhttps://www.002pc.com/python/946.html

你可能感兴趣的Python,pymysql,mysql,详解,模块,操作

关于我们 - 广告合作 - 联系我们 - 免责声明 - 网站地图 - 投诉建议 - 在线投稿

  浙ICP备140365454号

©CopyRight 2008-2020 002pc.COM Inc All Rights Reserved. 第二电脑网 版权所有 联系QQ:282523118