一。SQL注入是什么?
在xml动态拼接字段,但是拼接的这个字段,前端传给后端的时候,有可能被攻击者拦截。比如添加一个分号,sql语句等等,将用户名密码等信息拼接到分号后面。
二。如何解决SQL注入?
过滤掉常用的关键字,限制前端只能传属性,字段,而不能传关键字。我们设置一个SqlUtil工具类。只有符合我们指定规则的,才能放行,其他均抛异常,拦截。
三。实战
设置静态的关键字字符串,用 |分割,判断前端传来的东西,如果为空,什么也不用返回,不为空,将关键字分割(调用split方法),遍历关键字,遍历的过程中跟前端传来的东西匹配,如果能匹配,抛异常,如果不匹配就放行
四。SqlUtil工具类
package com.qy.common.utils.sql;
import com.qy.common.exception.UtilException;
import com.qy.common.utils.StringUtils;
/**
* sql操作工具类
*
* @author ww
*/
public class SqlUtil
{
/**
* 定义常用的 sql关键字
*/
public static String SQL_REGEX = "select |insert |delete |update |drop |count |exec |chr |mid |master |truncate |char |and |declare ";
/**
* 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
*/
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);
}
/**
* SQL关键字检查
* param value 前端传过来的东西
*/
public static void filterKeyword(String value)
{
//判断前端传来的是否为空
if (StringUtils.isEmpty(value))
{
return;
}
//将sql关键字通过\\|分割变成一个数组
String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
//遍历每一个关键字 就是select ,insert ,update ,
for (String sqlKeyword : sqlKeywords)
{
//如果前端传过来的东西能匹配 这些关键字,就抛异常
if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1)
{
throw new UtilException("参数存在SQL注入风险");
}
}
}
}
五。实战
在分页工具类PageUtil调用SqlUtil类,实现防止sql注入问题
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());