2019级软件工程应用与实践-人工智能快递柜(代码分析13)

2021SC@SDUSC

SQL注入处理

介绍

攻击者利用web应用程序对用户输入验证上的疏忽,在输入的数据中包含对某些数据库系统有特殊意义的符号或命令,让攻击者有机会直接对后台数据库系统下达指令,进而实现对后台数据库的入侵。

原理

SQL注入攻击的本质,服务端没有过滤用户输入的恶意数据,直接把用户输入的数据当作SQL语句执行,从而影响数据库安全和平台安全。

因此,在SQL注入时,应该对输入进行充分的检查,过滤用户的恶意数据

	private final static String TABLE_DICT_SIGN_SALT = "20200501";
	private final static String xssStr = "'|and |exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|or |+|,";

在表中可看到上线修改值为20200501
xssStr中包含了执行SQL语句的命令关键字、执行存储过程的命令关键字等等,他们可能会影响数据库的安全和平台安全,被称为注入关键字,需要对其进行过滤增强安全机制

public static void checkDictTableSign(String dictCode, String sign, HttpServletRequest request) {

		String accessToken = request.getHeader("X-Access-Token");
		String signStr = dictCode + SqlInjectionUtil.TABLE_DICT_SIGN_SALT + accessToken;
		String javaSign = SecureUtil.md5(signStr);
		if (!javaSign.equals(sign)) {
			log.error("表字典,SQL注入漏洞签名校验失败 :" + sign + "!=" + javaSign+ ",dictCode=" + dictCode);
			throw new JeecgBootException("无权限访问!");
		}
		log.info(" 表字典,SQL注入漏洞签名校验成功!sign=" + sign + ",dictCode=" + dictCode);
	}

针对表字典进行额外的sign签名校验,防止漏洞注入,增加安全机制

public static void filterContent(String value) {
		if (value == null || "".equals(value)) {
			return;
		}
		value = value.toLowerCase();
		String[] xssArr = xssStr.split("\\|");
		for (int i = 0; i < xssArr.length; i++) {
			if (value.indexOf(xssArr[i]) > -1) {
				log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
				log.error("请注意,值可能存在SQL注入风险!---> {}", value);
				throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
			}
		}
		return;
	}
	public static void filterContent(String[] values) {
		String[] xssArr = xssStr.split("\\|");
		for (String value : values) {
			if (value == null || "".equals(value)) {
				return;
			}
			// 统一转为小写
			value = value.toLowerCase();
			for (int i = 0; i < xssArr.length; i++) {
				if (value.indexOf(xssArr[i]) > -1) {
					log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
					log.error("请注意,值可能存在SQL注入风险!---> {}", value);
					throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
				}
			}
		}

将SQL注入数据统一转换成小写,通过for (int i = 0; i < xssArr.length; i++)循环,对xxArr中每一位数据进行检验,如果遇到注入关键字的话直接抛出异常

@Deprecated
	public static void specialFilterContent(String value) {
		String specialXssStr = " exec | insert | select | delete | update | drop | count | chr | mid | master | truncate | char | declare |;|+|";
		String[] xssArr = specialXssStr.split("\\|");
		if (value == null || "".equals(value)) {
			return;
		}
		// 统一转为小写
		value = value.toLowerCase();
		for (int i = 0; i < xssArr.length; i++) {
			if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) {
				log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
				log.error("请注意,值可能存在SQL注入风险!---> {}", value);
				throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
			}
		}
		return;
	}

特殊方法,仅用于字典条件SQL参数,注入过滤,不仅能通过value.indexOf(xssArr[i]) > -1进行判断,还可以通过value.startsWith(xssArr[i].trim())进行判断
startsWith()方法一般用于检测某请求字符串是否以指定的前缀开始的,如果含有注入关键字,则抛出异常。

@Deprecated
	public static void specialFilterContentForOnlineReport(String value) {
		String specialXssStr = " exec | insert | delete | update | drop | chr | mid | master | truncate | char | declare |";
		String[] xssArr = specialXssStr.split("\\|");
		if (value == null || "".equals(value)) {
			return;
		}
		// 统一转为小写
		value = value.toLowerCase();
		for (int i = 0; i < xssArr.length; i++) {
			if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) {
				log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
				log.error("请注意,值可能存在SQL注入风险!---> {}", value);
				throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
			}
		}
		return;
	}

特殊方法(不通用) 仅用于Online报表SQL解析,注入过滤。其处理原理和字典条件SQL参数一样。

相关拓展:手工检测SQL注入漏洞

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值