pymysql模块的基本使用,防mysql注入
pymysql模块的基本使用
pymysql模块的注意事项:
1、连接数据裤的时候,connect下的编码参数不能有’-‘ 例如:utf-8 要写成utf8,否则会报错。
2、创建光标的时候,可以添加cursor=pymysql.cursors.DictCursor这个参数,这样获取的结果会以字典的形式返回。
3、光标的文本读取光标一样,光标每获取一次执行结果,光标都会停留在那个位置。
4、pymysql执行增删改操作的时候,需要二次确定才可以修改数据
二次确定的方法:
(1)在操作成功后添加这个语句 conn.commit()
(2)直接在连接数据库的时候,加入一个参数autocommit=True,这样每次修改数据就会自动提交。
5、执行多条数据插入的时候,可以用executemany方法,cusor.executemany(sql,[(),(),()]),即把多条数据放到一个列表中。
#例如: cusor.fetchone() #执行结果是获取的是表中第一条数据, cusor.fetchone() #执行结果是获取表中的第二条数据
3、光标下的scroll方法下的两个模式:
#该模式下参数,表示光标移动的位置,1就表示光标从当前位置, #往后移动一位 cusor.scroll(1,mode='relative') #该模式下参数代表光标的位置,0 表示最起始位置。 cusor.scroll(0,mode='absolute')
具体例子代码详解如下:
#pymysql模块下的 connect方法参数源码如下: def __init__(self, host=None, user=None, password="", database=None, port=0, unix_socket=None, charset='', sql_mode=None, read_default_file=None, conv=None, use_unicode=None, client_flag=0, cursorclass=Cursor, init_command=None, connect_timeout=10, ssl=None, read_default_group=None, compress=None, named_pipe=None, autocommit=False, db=None, passwd=None, local_infile=False, max_allowed_packet=16*1024*1024, defer_connect=False, auth_plugin_map=None, read_timeout=None, write_timeout=None, bind_address=None, binary_prefix=False, program_name=None, server_public_key=None): #光标下的sroll方法源码: def scroll(self, value, mode='relative'): self._check_executed() if mode == 'relative': r = self.rownumber + value elif mode == 'absolute': r = value else: raise err.ProgrammingError("unknown scroll mode %s" % mode) if not (0 <= r < len(self._rows)): raise IndexError("out of range") self.rownumber = r
mysql基本使用实例代码如下:
# -*-coding:utf-8 -*- import pymysql conn = pymysql.connect( host='localhost', port=3306, user='用户名', password='密码', db='day46', charset='utf8' #字符编码不能加-,否则会报错 ) #cursor=pymysql.cursors.DictCursor将返回的结果以字典的形式返回 #注意:光标跟读取文本的光标一样,每次执行语句后,光标会停留在执行结果的位置, # 比如,这次执行结果取了两条数据,下次取数据就是从第三条开始取。 cusor=conn.cursor(cursor=pymysql.cursors.DictCursor) #光标 sql='select * from right_b' res=cusor.execute(sql) print(res) print(cusor.fetchone()) #取一条 #该模式下参数,表示光标移动的位置,1就表示光标从当前位置, 往后移动一位 cusor.scroll(1,mode='relative') #取两条,括号里的参数2表示取的数据条数 print(cusor.fetchmany(2)) #该模式下参数代表光标的位置 cusor.scroll(0,mode='absolute') #取所有数据 print(cusor.fetchall())
执行结果如下:
增删改查操作的具体例子如下:
# -*-coding:utf-8 -*- import pymysql conn = pymysql.connect( host='localhost', port=3306, user='root', password='root', db='day46', charset='utf8' #字符编码不能加-,否则会报错 ) cusor=conn.cursor(cursor=pymysql.cursors.DictCursor) print( ''' -------------菜单-------------- 1、注册 2、登陆 3、更改用户名 4、删除用户 ''' ) #判断操作是否成功的方法 def comit(sql,arg): print(arg) row = cusor.execute(sql,arg) #插入多条数据,就用该方法,把每条数据放到列表中的每一个元组里。 # cusor.executemany(sql, [(), (),()] if row: print('成功') conn.commit() else: print('失败') while True: choice=input("你的选择>>:") if choice=='1': name = input("用户名>>:") pwd = input("密码>>:") # sql="select * from user where name='%s' and passwd='%s'"%(name,pwd) sql = "select * from user where name=%s" row = cusor.execute(sql, (name,)) if row: print('注册失败,用户名已存在') else: r_sql="insert into user(name,passwd) values(%s,%s)" comit(r_sql, (name, pwd)) elif choice=='2': name=input("用户名>>:") pwd=input("密码>>:") # sql="select * from user where name='%s' and passwd='%s'"%(name,pwd) sql="select * from user where name=%s and passwd=%s" comit(sql, (name, pwd)) elif choice=='3': name=input("旧用户名>>:") new_name=input("新用户名>>:") sql='update user set name=%s where name=%s' comit(sql,(new_name,name)) elif choice=='4': name=input('用户名>>:') sql='delete from user where name=%s' comit(conn,sql,(name,))
注入主要利用的是mysql的语法漏洞:
第一种:知道用户名的情况下,利用mysql的注释符号把密码给注释掉
select * from user where name='root' -- ajgldsja' and passwd='';
第二种:不知道密码跟用户名,利用布尔盲注
select * from user where name='xxx' or 1=1 -- ajgljsd'' and passwd='';
mysql注入具体实例代码如下:
import pymysql conn = pymysql.connect( host='localhost', port=3306, user='root', password='密码', db='day46', charset='utf8' #字符编码不能加-,否则会报错 ) cusor=conn.cursor(cursor=pymysql.cursors.DictCursor) name=input("用户名>>:") pwd=input("密码>>:") sql="select * from user where name='%s' and passwd='%s';"%(name,pwd) print(sql) row =cusor.execute(sql) if row: print('登陆成功') print(cusor.fetchall()) else: print('登陆失败')
防止mysql注入的方法:
就是用%s给参数留位置,不直接对sql语句进行拼接,把用户名、密码这两个参数通过execute方法传进去
# sql="select * from user where name='%s' and passwd='%s'"%(name,pwd) sql="select * from user where name=%s and passwd=%s" cusor.execute(sql,(name,pwd))
具体完整代码如下:
# -*-coding:utf-8 -*- import pymysql conn = pymysql.connect( host='localhost', port=3306, user='root', password='root', db='day46', charset='utf8' #字符编码不能加-,否则会报错 ) cusor=conn.cursor(cursor=pymysql.cursors.DictCursor) name=input("用户名>>:") pwd=input("密码>>:") # sql="select * from user where name='%s' and passwd='%s'"%(name,pwd) sql="select * from user where name=%s and passwd=%s" print(sql) row =cusor.execute(sql,(name,pwd)) if row: print('登陆成功') print(cusor.fetchall()) else: print('登陆失败')
注入测试结果:
不将就