SpringBoot如何避免SQL注入漏洞呢?

转自:

SpringBoot如何避免SQL注入漏洞呢?

下文笔者讲述SpringBoot避免SQL注入漏洞的方法分享,如下所示

SQL盲注,SQL注入简介

 SQL注入的风险:
     数据库中的数据被任意查看,修改,删除
 SQL注入的原因:
     未对用户输入进行正确的验证
 SQL注入如何避免
     对危险字符进行过滤或sql参数化

SQL注入避免示例

 添加SQL注入包装类 
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
/**
 * SQL注入包装类
 * 
 * @author java265
 *
 */
 
public class SqlInjectHttpServletRequestWrapper extends HttpServletRequestWrapper {
    public static final Logger log = LoggerFactory.getLogger(SqlInjectHttpServletRequestWrapper .class);
	/**
	 * 构造请求对象
	 * 
	 * @param request
	 */
	public SqlInjectHttpServletRequestWrapper(HttpServletRequest request) {
		super(request);
	}
 
	/**
	 * 获取头部参数
	 * 
	 * @param v 参数值
	 */
	@Override
	public String getHeader(String v) {
		String header = super.getHeader(v);
		if (header == null || "".equals(header)) {
			return header;
		}
		return sqlFilter(header);
	}
 
	/**
	 * 获取参数
	 * 
	 * @param v 参数值
	 */
	@Override
	public String getParameter(String v) {
		String param = super.getParameter(v);
		if (param == null || "".equals(param)) {
			return param;
		}
		return sqlFilter(param);
	}
 
	/**
	 * 获取参数值
	 * 
	 * @param v 参数值
	 */
	@Override
	public String[] getParameterValues(String v) {
		String[] values = super.getParameterValues(v);
		if (values == null) {
			return values;
		}
 
		int length = values.length;
		String[] resultValues = new String[length];
		for (int i = 0; i < length; i++) {
			// 过滤特殊字符
			resultValues[i] = sqlFilter(values[i]);
			if (!(resultValues[i]).equals(values[i])) {
				log.debug("SQL注入过滤器 => 过滤前:{} => 过滤后:{}", values[i], resultValues[i]);
			}
		}
		return resultValues;
	}
 
	/**
	 * 预编译SQL过滤正则表达式
	 */
	private Pattern sqlPattern = Pattern.compile(
			"(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)\\b)",
			Pattern.CASE_INSENSITIVE);
 
	/**
	 * SQL过滤
	 * 
	 * @param v 参数值
	 * @return
	 */
	private String sqlFilter(String v) {
		if (v != null) {
			String resultVal = v;
			Matcher matcher = sqlPattern.matcher(resultVal);
			if (matcher.find()) {
				resultVal = matcher.replaceAll("");
			}
			if (!resultVal.equals(v)) {
				return "";
			}
			return resultVal;
		}
		return null;
	}
}

3、配置文件添加配置
# sql 注入过滤url地址
security.sql.excludes=/images/*, /jquery/*, /layui/*

4、添加SQL注入过滤器
import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Value;
 
/**
 * SQL注入过滤器
 * 
 * @author java265
 *
 */
@Component
@WebFilter(filterName = "SqlInjectFilter", urlPatterns = "/*")
public class SqlInjectFilter implements Filter {
 
	/**
	 * 过滤器配置对象
	 */
	FilterConfig filterConfig = null;
 
	/**
	 * 是否启用(默认启用)
	 */
	private boolean enable = true;
 
 
	/**
	 * 忽略的URL
	 */
    @Value("${security.sql.excludes}")
	private String excludes;
 
 
	/**
	 * 初始化
	 */
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		this.filterConfig = filterConfig;
	}
 
	/**
	 * 拦截
	 */
	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) servletRequest;
 
		// 不启用或者已忽略的URL不拦截
		if (!enable || isExcludeUrl(request.getServletPath())) {
			filterChain.doFilter(servletRequest, servletResponse);
			return;
		}
		SqlInjectHttpServletRequestWrapper sqlInjectHttpServletRequestWrapper = new SqlInjectHttpServletRequestWrapper(
				request);
		filterChain.doFilter(sqlInjectHttpServletRequestWrapper, servletResponse);
	}
 
	/**
	 * 销毁
	 */
	@Override
	public void destroy() {
		this.filterConfig = null;
	}
 
	/**
	 * 判断是否为忽略的URL
	 * 
	 * @param urlPath URL路径
	 * @return true-忽略,false-过滤
	 */
	private boolean isExcludeUrl(String url) {
		if (excludes == null || excludes.isEmpty()) {
			return false;
		}
        List<String> urls = Arrays.asList(excludes.split(","));
		return urls .stream().map(pattern -> Pattern.compile("^" + pattern)).map(p -> p.matcher(url))
				.anyMatch(Matcher::find);
	}
}
Spring Boot 是基于 Spring 框架构建的,它可以通过自动配置和约定大于配置的方式来轻松创建独立的、生产级别的 Spring 应用程序。然而,Spring Boot 也存在 SQL 注入的风险,因此我们需要掌握相应的防范措施。 SQL 注入漏洞是指黑客利用合法的 SQL 查询接口,向应用程序的后台数据库发送针对数据库的攻击字符串,获取数据库的机密信息或通过修改数据库来破坏系统的安全性。在 Spring Boot 中,SQL 注入漏洞通常出现在动态拼接 SQL 语句的场景中,如使用 JdbcTemplate 进行数据库操作或通过 MyBatis 操作数据库时,如果不做正确的防范,就很容易发生 SQL 注入漏洞。 为了避免 SQL 注入漏洞的问题,我们可以采取以下措施: 1. 使用预处理语句:建议使用预处理语句,这样可以将传入的参数当做参数来处理,而不是当做 SQL 语句的一部分来处理。预处理语句可以有效地解决 SQL 注入问题,也可以提高应用程序的性能。 2. 使用参数中转:使用参数中转可以将直接拼接 SQL 语句的方式改为将参数值插入到预定义的 SQL 语句当中,从而避免 SQL 注入漏洞的风险。 3. 遵循安全编码规范:在进行开发工作时,应该遵循安全编码规范,对输入参数进行合理的检查和过滤,确保不会将恶意的输入传递给后台 SQL 语句。 总而言之,为了防范 SQL 注入漏洞,我们需要采取多种措施,如使用预处理语句、使用参数中转和遵循安全编码规范等,以确保应用程序的安全性。同时,开发人员也要不断学习新的安全技术和解决方案,提高系统的安全性和鲁棒性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值