防sql注入 盲注等措施 ESAPI的使用
SQL注入往往是在程序员编写包含用户输入的动态数据库查询时产生的,但其实防范SQL注入的方法非常简单。程序员只要a)不再写动态查询,或b)防止用户输入包含能够破坏查询逻辑的恶意SQL语句,就能够防范SQL注入。在这篇文章中,我们将会说明一些非常简单的防止SQL注入的方法。
我们用以下Java代码作为示例,
String query ="SELECT account_balance FROM user_data WHERE user_name ="
+ request.getParameter("customerName");
try {
Statement statement = connection.createStatement( …);
ResultSet results = Statement.executeQuery(query);
}
在以上代码中,我们可以看到并未对变量customerName做验证,customerName的值可以直接附在query语句的后面传送到数据库执行,则攻击者可以将任意的sql语句注入。
防范方法1:参数化查询
参数化查询是所有开发人员在做数据库查询时首先需要学习的,参数化查询迫使所有开发者首先要定义好所有的SQL代码,然后再将每个参数逐个传入,这种编码风格就能够让数据库辨明代码和数据。
参数化查询能够确保攻击者无法改变查询的内容,在下面修正过的例子中,如果攻击者输入了UsrID是“’or ‘1 ‘=’1”,参数化查询会去查找一个完全满足名字为‘or ‘1 ‘=’ 1的用户。
对于不同编程语言,有一些不同的建议:
Java EE——使用带绑定变量的PreparedStatement();
.Net——使用带绑定变量的诸如SqlCommand()或OleDbCommand()的参数化查询;
PHP——使用带强类型的参数化查询PDO(使用bindParam());
Hibernate——使用带绑定变量的createQuery()。
Java示例:
String custname = request.getParameter("customerName");
String query ="SELECT account_balance FROM user_data WHERE user_name= ?";
PreparedStatement pstmt = connection.prepareStatement(query);
Pstmt.setString(1,custname);
ResultSet results = pstmt.executeQuery();
C# .Net示例:
String query ="SELECT account_balance FROM user_data WHERE user_name = ?";
Try {
OleDbCommand command = new OleDbCommand(query,connection);
command.Parameters.Add(new OleDbParameter("customerName",CustomerName.Text));
OleDbDataReader reader = command.ExecuteReader();
}catch (OleDbException se){
//error handling
}
防范方法二:存储过程
存储过程和参数化查询的作用是一样的,唯一的不同在于存储过程是预先定义并存放在数据库中,从而被应用程序调用的。
Java存储过程示例:
String custname = request.getParameter("customerName");
try {
CallableStatement cs = connection.prepareCall("call sp_getAccountBalance(?)}");
cs.setString(1,custname);
Result results = cs.executeQuery();
}catch(SQLException se){
//error handling
}
VB .Net存储过程示例:
Try
Dim command As SqlCommand = new SqlCommand("sp_getAccountBalance",connection)
command.CommandType = CommandType.StoredProcedure
command.Parameters.Add(new SqlParameter("@CustomerName",CustomerName.Text))
Dim reader As SqlDataReader = command.ExecuteReader()
‘…
Catch se As SqlException
‘error handling
End Try
防范方法三:对所有用户输入进行转义
我们知道每个DBMS都有一个字符转义机制来告知DBMS输入的是数据而不是代码,如果我们将所有用户的输入都进行转义,那么DBMS就不会混淆数据和代码,也就不会出现SQL注入了。
当然,如果要采用这种方法,那么你就需要对所使用的数据库转义机制,也可以使用现存的诸如OWASP ESAPI的escaping routines。ESAPI目前是基于MySQL和Oracle的转义机制的,使用起来也很方便。一个Oracle的ESAPI的使用示例如下:
ESAPI.encoder().encodeForSQL(new OracleCodec(),queryparam);
那么,假设你有一个要访问Oracle数据库的动态查询代码如下:
String query ="SELECT user_id FROM user_data WHERE user_name = ‘"+req.getParameter("userID")+"’ and user_password = ‘"+req.getParameter("pwd")+"’";
try {
Statement statement = connection.createStatement(…);
ResultSet results = statement.executeQuery(query) ;
}
那么,你就必须重写你的动态查询的第一行如下:
Codec ORACLE_CODEC = new OracleCodec();
String query ="SELECT user_id FROM user_data WHERE user_name = ‘"+
ESAPI.encoder().encodeForSQL(ORACLE_CODEC,req.getParameter("userID"))+"’ and user_password = ‘"+
ESAPI.encoder().encodeForSQL(ORACLE_CODEC,req.getParameter("pwd"))+"’";
当然,为了保证自己代码的可读性,我们也可以构建自己的OracleEncoder:
Encoder e = new OracleEncoder();
String query ="SELECT user_id FROM user_data WHERE user_name = ‘"
+ oe.encode(req.getParameter("userID")) +"’ and user_password = ‘"
+ oe.encode(req.getParameter("pwd"))+"’";
除了上面所说的三种防范方法以外,我们还建议可以用以下两种附加的方法来防范SQL注入:最小权限法、输入验证白名单法。
最小权限法:
为了避免注入攻击对数据库造成的损害,我们可以把每个数据库用户的权限尽可能缩小,不要把DBA或管理员的权限赋予你应用程序账户,在给用户权限时是基于用户需要什么样的权限,而不是用户不需要什么样的权限。当一个用户只需要读的权限时,我们就只给他读的权限,当用户只需要一张表的部分数据时,我们宁愿另建一个视图让他访问。
如果你的策略是都是用存储过程的话,那么仅允许应用程序的账户执行这些查询,而不给他们直接访问数据库表的权限。诸如此类的最小权限法能够在很大程度上保证我们数据库的安全。
输入验证白名单法:
输入验证能够在数据传递到SQL查询前就察觉到输入是否正确合法,采用白名单而不是黑名单则能在更大程度上保证数据的合法性。
防sql注入 盲注等措施 ESAPI的使用的更多相关文章
- SQL注入--盲注及报错注入
盲注查询 盲注其实就是没有回显,不能直观地得到结果来调整注入数据,只能通过其他方式来得到是否注入成功,主要是利用了一些数据库内置函数来达到的 布尔盲注 布尔很明显Ture跟Fales,也就是说它只会根 ...
- SQL注入 盲注
来源:http://www.cnblogs.com/cheatlove/articles/384233.html SQL注入攻击: (1) 脚本注入式的攻击(2) 恶意用户输入用来影响被执行的SQL脚 ...
- SQL注入----盲注总结
参考文章:https://mp.weixin.qq.com/s?__biz=MzIzMTc1MjExOQ==&mid=2247490388&idx=1&sn=c677837d7 ...
- 关于sql注入盲注,谈谈自己的心得
1.没做防御的站点,拿上sqlmap直接怼就行了. 2.做了防御,有的用函数过滤了,有的用了waf(比如安全狗,云锁,华为云waf,360waf,知道创宇盾,护卫神等等) 这些就相当麻烦了,首先要探测 ...
- PHP防SQL注入不要再用addslashes和mysql_real_escape_string
PHP防SQL注入不要再用addslashes和mysql_real_escape_string了,有需要的朋友可以参考下. 博主热衷各种互联网技术,常啰嗦,时常伴有强迫症,常更新,觉得文章对你有帮助 ...
- Sqlparameter防SQL注入
一.SQL注入的原因 随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多.但是由于这个行业的入门门槛不高,程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对 ...
- 【荐】PDO防 SQL注入攻击 原理分析 以及 使用PDO的注意事项
我们都知道,只要合理正确使用PDO,可以基本上防止SQL注入的产生,本文主要回答以下几个问题: 为什么要使用PDO而不是mysql_connect? 为何PDO能防注入? 使用PDO防注入的时候应该特 ...
- C#语言Winform防SQl注入做用户登录的例子
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...
- mysql之数据库连接的方法封装及防sql注入
一.定义数据库和表 create database animal; CREATE TABLE `pet` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name ...
随机推荐
- Codeforces 545E. Paths and Trees[最短路+贪心]
[题目大意] 题目将从某点出发的所有最短路方案中,选择边权和最小的最短路方案,称为最短生成树. 题目要求一颗最短生成树,输出总边权和与选取边的编号.[题意分析] 比如下面的数据: 5 5 1 2 2 ...
- Python脚本实现值更新事件赋值过程记录日志监控
#LogWatch 实现值更新事件赋值过程记录日志监控 clr.AddReference('System') clr.AddReference('Kingdee.BOS') clr.AddRefere ...
- javaweb学习总结(八)——HttpServletResponse对象(二)(转)
(每天都会更新至少一篇以上,有兴趣的可以关注)转载自孤傲苍狼 一.HttpServletResponse常见应用——生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedI ...
- ElasticSearch中Filter和Query的异同
如下例子,查找性别是女,所在的州是PA,过滤条件是年龄是39岁,balance大于等于10000的文档: { "query": { "bool": { &quo ...
- 【BZOJ2049】洞穴勘测(LCT)
题意:一张图,要求支持以下操作: 1.加边 2.删边 3.询问两点之间是否联通 100%的数据满足n≤10000, m≤200000 思路:LCT裸题,不需要维护任何信息 ..,..]of longi ...
- calc BZOJ 2655
calc [问题描述] 一个序列a1,...,an是合法的,当且仅当: 长度为给定的n. a1,...,an都是[1,A]中的整数. a1,...,an互不相等. 一个序列的值定义为它里面所有数的乘积 ...
- PXC小结
PXC使用到的端口号 3306 数据库对外服务的端口号(视具体情况而定) 4444 请求SST SST: 指数据一个镜象传输 xtrabackup , rsync ,mysqldump 4567 : ...
- 【C++】DLL内共享数据区在进程间共享数据(重要)
因项目需要,需要在DLL中共享数据,即DLL中某一变量只执行一次,在运行DLL中其他函数时该变量值不改变:刚开始想法理解错误,搜到了DLL进程间共享数据段,后面发现直接在DLL中定义全局变量就行,当时 ...
- (10) android控件-date
1.TimePicker <TimePicker android:id="@+id/timePicker4" android:layout_width="wrap_ ...
- Codeforces Gym 100286J Javanese Cryptoanalysis 傻逼暴力
原题地址:http://codeforces.com/gym/100286/attachments/download/2013/20082009-acmicpc-northeastern-europe ...