pymysql解决sql注入问题的示例分析

  介绍

这篇文章将为大家详细讲解有关pymysql解决sql注入问题的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

<强> 1。SQL注入

SQL注入是非常常见的一种网络攻击方式,主要是通过参数来让mysql执行SQL语句时进行预期之外的操作。

即:因为传入的参数改变SQL的语义,变成了其他命令,从而操作了数据库。

产生原因:SQL语句使用了动态拼接的方式。

例如,下面这段代码通过获取用户信息来校验用户权限:

import  pymysql=sql  & # 39; SELECT  count (*), as  count 得到user  WHERE  id =, & # 39;, +, str(输入[& # 39;id # 39;]), +, & # 39;,以及password =,“& # 39;, +,输入[& # 39;密码# 39;],+,& # 39;“& # 39;   时间=cursor  dbclient.cursor (pymysql.cursors.DictCursor)   cursor.execute (sql)   时间=count  cursor.fetchone ()   if  count  is  not  None 以及计算[& # 39;计数# 39;],祝辞,0:   ,打印(& # 39;登陆成功& # 39;)

但是,如果传入参数是:

输入[& # 39;id # 39;],=, & # 39; 2,或1=1 & # 39;

你会发现,用户能够直接登录到系统中,因为原sql语本句的判断条件被或短路成为了永远正确的语句。
这里仅仅是举一个例子,事实上,sql注入的方式还有很多种,这里不深入介绍了。

总之,只要是通过用户输入数据来拼接sql语句,就必须在第一时间考虑如何避免sql注入问题。

那么,如何防止sql注入呢?

<强> 2。预防SQL注入——pymysql参数化语句

pymysql的执行支持参数化SQL,通过占位符% s配合参数就可以实现SQL注入问题的避免。

import  pymysql      时间=sql  & # 39; SELECT  count (*), as  count 得到user  WHERE  id =, % s 以及password =, % & # 39;   时间=valus [输入[& # 39;id # 39;],,输入[& # 39;密码# 39;]]   时间=cursor  dbclient.cursor (pymysql.cursors.DictCursor)   cursor.execute (sql,,值)   时间=count  cursor.fetchone ()   if  count  is  not  None 以及计算[& # 39;计数# 39;],祝辞,0:   ,打印(& # 39;登陆成功& # 39;)

这样参数化的方式,让mysql通过预处理的方式避免了sql注入的存在。

需要注意的是,不要因为参数是其他类型而换掉% s, pymysql的占位符并不是python的通用占位符。

同时,也不要因为参数是字符串就在% s两边加引号,mysql会自动去处理。

<强> 3。预防SQL注入——mysql存储过程

数据库存储过程是mysql的一种高级用法,但是一般来说,并不建议使用数据库的存储过程。

<强>主要原因是:

<李>

存储过程的语法与普通SQL语句语法相差太大,增加维护成本

<李>

存储过程在各数据库间不通用且差别较大,给数据库的移植和扩展带来困难

<李>

编写困难,数据库脚本语言使用起来还是很不方便的,包括很多数据结构的缺失,让很多事情做起来很困难

<李>

调试困难,虽然有一些功能强大的IDE提供了数据库存储过程的调试功能,但是通常你需要同时在数据库层面上和业务中同时进行调试,两处调试极为不便

<李>

业务耦合,编写存储过程通常是需要在其中放入部分业务逻辑,这使得业务分散在数据层、业务层与数据层的耦合对于项目维护和扩展都会带来极大地不便。

但是,虽然不建议使用存储过程,但是毕竟可以依赖他实现各种跨语言的SQL注入预防,在复杂的场景下还是有其使用价值的。(以后需要用再去详细学,这里只作简单介绍)

<强> 3.1。存储过程编写

delimiter  \ DROP  PROCEDURE  IF  EXISTS  proc_sql  \ CREATE  PROCEDURE  proc_sql  (   ,nid1 拷贝,INT,   ,nid2 拷贝,INT,   ,拷贝callsql  VARCHAR (255)   )   开始   ,set  @nid1 =, nid1;   ,set  @nid2 =, nid2;   ,set  @callsql =, callsql;   得到@callsql获,PREPARE  myprod ;   ,——PREPARE  prod 得到& # 39;select  *,得到tb2  where  nid> ?,以及nid<? & # 39;;信息,传入的值为字符串,?为占位符   ,——用@p1,和@p2填充占位符   ,EXECUTE  myprod  USING  @nid1 @nid2;   ,DEALLOCATE  prepare  myprod;      结束\ delimiter ;

pymysql解决sql注入问题的示例分析