pymysql 解决 sql 注入问题
1. SQL 注入
SQL 注入是非常常见的一种网络攻击方式,主要是通过参数来让 mysql 执行 sql 语句时进行预期之外的操作。
即:因为传入的参数改变SQL的语义,变成了其他命令,从而操作了数据库。
产生原因:SQL语句使用了动态拼接的方式。
例如,下面这段代码通过获取用户信息来校验用户权限:
import pymysql sql = 'SELECT count(*) as count FROM user WHERE id = ' + str(input['id']) + ' AND password = "' + input['password'] + '"'
cursor = dbclient.cursor(pymysql.cursors.DictCursor)
cursor.execute(sql)
count = cursor.fetchone()
if count is not None and count['count'] > 0:
print('登陆成功')
但是,如果传入参数是:
input['id'] = '2 or 1=1'
你会发现,用户能够直接登录到系统中,因为原本 sql 语句的判断条件被 or 短路成为了永远正确的语句。
这里仅仅是举一个例子,事实上,sql 注入的方式还有很多种,这里不深入介绍了。
总之,只要是通过用户输入数据来拼接 sql 语句,就必须在第一时间考虑如何避免 SQL 注入问题。
那么,如何防止 SQL 注入呢?
2. 预防 SQL 注入 – pymysql 参数化语句
pymysql 的 execute 支持参数化 sql,通过占位符 %s 配合参数就可以实现 sql 注入问题的避免。
import pymysql sql = 'SELECT count(*) as count FROM user WHERE id = %s AND password = %s'
valus = [input['id'], input['password']]
cursor = dbclient.cursor(pymysql.cursors.DictCursor)
cursor.execute(sql, values)
count = cursor.fetchone()
if count is not None and count['count'] > 0:
print('登陆成功')
这样参数化的方式,让 mysql 通过预处理的方式避免了 sql 注入的存在。
需要注意的是,不要因为参数是其他类型而换掉 %s,pymysql 的占位符并不是 python 的通用占位符。
同时,也不要因为参数是 string 就在 %s 两边加引号,mysql 会自动去处理。
3. 预防 SQL 注入 – mysql 存储过程
数据库存储过程是 mysql 的一种高级用法,但是一般来说,并不建议使用数据库的存储过程。
主要原因是:
- 存储过程的语法与普通 SQL 语句语法相差太大,增加维护成本
- 存储过程在各数据库间不通用且差别较大,给数据库的移植和扩展带来困难
- 编写困难,数据库脚本语言使用起来还是很不方便的,包括很多数据结构的缺失,让很多事情做起来很困难
- 调试困难,虽然有一些功能强大的 IDE 提供了数据库存储过程的调试功能,但是通常你需要同时在数据库层面上和业务中同时进行调试,两处调试极为不便
- 业务耦合,编写存储过程通常是需要在其中放入部分业务逻辑,这使得业务分散在数据层,业务层与数据层的耦合对于项目维护和扩展都会带来极大地不便。
但是,虽然不建议使用存储过程,但是毕竟可以依赖他实现各种跨语言的 sql 注入预防,在复杂的场景下还是有其使用价值的。(以后需要用再去详细学,这里只作简单介绍)
3.1. 存储过程编写
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 ;
3.2. pymsql 中调用
import pymysql cursor = conn.cursor()
mysql="SELECT * FROM user where nid > ? and nid < ?"
cursor.callproc('proc_sql', args=(11, 15, mysql))
rows = cursor.fetchall()
conn.commit()
pymysql 解决 sql 注入问题的更多相关文章
- Navicat工具、pymysql模块 sql注入
cls超 Navicat工具.pymysql模块 阅读目录 一 IDE工具介绍 二 pymysql模块 一 IDE工具介绍(Navicat) 生产环境还是推荐使用mysql命令行,但为了方便我们测试, ...
- IBatis.Net使用总结(一)-- IBatis解决SQL注入(#与$的区别)
IBatis解决SQL注入(#与$的区别) 在IBatis中,我们使用SqlMap进行Sql查询时,需要引用参数,在参数引用中可以使用两种占位符#和$.这两种占位符有什么区别呢? (1):#***#, ...
- PreparedStatement解决sql注入问题
总结 PreparedStatement解决sql注入问题 :sql中使用?做占位符 2.得到PreparedStatement对象 PreparedStatement pst=conn.prepar ...
- 使用过滤器解决SQL注入和跨站点脚本编制
1 SQL注入.盲注 1.1 SQL注入.盲注概述 Web 应用程序通常在后端使用数据库,以与企业数据仓库交互.查询数据库事实上的标准语言是 SQL(各大数据库供应商都有自己的不同版本).Web 应用 ...
- 解决 SQL 注入的另类方法
本文是翻译,版权归原作者所有 原文地址(original source):https://bitcoinrevolt.wordpress.com/2016/03/08/solving-the-prob ...
- MyBatis是如何解决Sql注入的
转:[转]mybatis如何防止sql注入 java中预处理PrepareStatement为什么能起到防止SQL注入的作用??!! 一.SQL注入 sql注入大家都不陌生,是一种常见的攻击方式,攻击 ...
- MySQL_(Java)使用preparestatement解决SQL注入的问题
MySQL_(Java)使用JDBC向数据库发起查询请求 传送门 MySQL_(Java)使用JDBC创建用户名和密码校验查询方法 传送门 MySQL数据库中的数据,数据库名garysql,表名gar ...
- JDBC_08_解决SQL注入问题 (登录和注册)
解决SQL注入问题 只要用户提供的信息不参与sql语句的编译过程,那么尽管用户输入的信息中含有sql关键字那么也不会起作用了 要想使用户提供信息不参与sql语句的编译过程,那么必须使用 java.sq ...
- jdbc 07: 解决sql注入
jdbc连接mysql,解决sql注入问题 package com.examples.jdbc.o7_解决sql注入; import java.sql.*; import java.util.Hash ...
随机推荐
- pair project elevator
结对编程——电梯调度 12061181 高孟烨 12061182 郝倩 1.结对编程的优缺点: 优点:结对编程可以结合两个人各自擅长之地,充分发挥两个人各自的优势,两个人一起合作效率会更高.一份工作两 ...
- 《蹭课神器》Beta版使用说明
相比 Alpha 版,我对主界面进行了优化,使主界面更加简洁 同时数据库增加了一个表,里面存放的是课程的详细信息
- HTTP Client使用总结
1.如果服务器使用HTTPS协议,使用HTTPClient的话,需要配以EasySSLProtocolSocketFactory 2.Tomcat对HTTP的Post和Get请求处理是不一样的.Spr ...
- about use Vue of methods
methods 处理事件 methods 在vue中处理一些逻辑方面的事情.vue事件监听的方式看上去有点违背分离的传统观念.而实际上vue中所有事件的处理方式和表达式都是严格绑定在当前的视图的vie ...
- CentOS yum 安装获取原始rpm文件的方法
1. 有时候 yum install 需要从几个repo下载rpm包速度很慢,不如自己能够将rpm包下载下来继续使用,比较好. 发现yum install 有两种方式能够将下载的rpm包保存下来. 方 ...
- 《使用swoole》
第一 在windows系统搭建swoole环境: 首先,安装cygwin:步骤截图如下 其次,使用cygwin安装swoole: 打开cygwin的终端,进入~目录,并将swoole-src上传到~目 ...
- LODOP弹出对话框获取保存文件的路径
通常一般不会让用户自己在文本框里填上路径,因为路径要输入字母字符等比较麻烦,而且用户硬盘里文件很多,也不知道要保存在哪里,LODOP可以弹出一个选择保存路径的弹窗,然后把返回选择的路径值.这样用户就可 ...
- mysql 分页数据错乱
最近在使用mysql 分页查询数据的时候发现返回的数据与预期的不一样,显示数据重复错乱. 在官方文档 有这样一句话 If multiple rows have identical values in ...
- 【Sublime Text3】Package Control:Install Package不能使用解决方法
官网地址 https://packagecontrol.io/installation 报错内容 解决方法 https://packagecontrol.io/docs/troubleshoo ...
- Codeforces Round #440 (Div. 2) A,B,C
A. Search for Pretty Integers time limit per test 1 second memory limit per test 256 megabytes input ...