java order by 防止注入的方法
防注入方法
/**
* 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
*/
public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
/**
* 检查字符,防止注入绕过
*/
public static String escapeOrderBySql(String value)
{
if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value))
{
throw new UtilException("参数不符合规范,不能进行查询");
}
return value;
}
/**
* 验证 order by 语法是否符合规范
*/
public static boolean isValidOrderBySql(String value)
{
return value.matches(SQL_PATTERN);
}
调用escapeOrderBySql()
方法就可以对order by后的字符进行验证,如果出现了特殊符号那么直接抛出异常,如果字符合法那么原样返回。
SQL注入类型
按照注入点类型来分类
(1).数字型注入点(当输入的参数为整形时,如果存在注入漏洞,可以认为是数字型注入。)
sql原型: select * from aaa where id = 1
,有如下种可能:
1). 加单引号,对应的sql: select * from aaa where id=3’
这时sql语句出错,程序无法正常从数据库中查询出数据,就会抛出异常;
2).加or 1=1,对应的sql: select * from aaa where id=3 or 1=1
这个时候能够查询到所有的结果
3).加上 and 1=1 对应的sql:select * from aaa where id=3 and 1=1
不能查询到结果
(2).字符型注入点(当输入的参数为字符串时,称为字符型。字符型和数字型最大的一个区别在于,数字型不需要单引号来闭合,而字符串一般需要通过单引号来闭合的。)
sql原型: select * from aaa where name='admin'
,有如下种可能:
1).加单引号:
select * from aaa where name ='admin' and 1=1 -- '
这种注入方式并不会影响查询结果
2).加union:
select name from aaa where name='1' union select database()#'
这种的结果就是把数据库信息泄露出去。
3).加or
select name from aaa where name='11' or '1234 '='1234'
这种就是导致查询的结果并不是期望的结果,导致数据泄露
(3).搜索型注入点(说明一下,搜索型注入也无他,前加%'
后加 and '%'='
对于MYSQL数据库,后面可以把 and '%'='
换成--
)
这是一类特殊的注入类型。这类注入主要是指在进行数据搜索时没过滤搜索参数,一般在链接地址中有“keyword=关键字”,有的不显示在的链接地址里面,而是直接通过搜索框表单提交。此类注入点提交的 SQL 语句,其原形大致为:select * from 表名 where 字段 like '%关键字%'
。
更多:
从orderby引发的SQL注入问题的思考 - 冯廷鑫 - 博客园