以下问题均出现在集团对项目的安全检测中,以前一直以为安全问题离我很远,自己代码的不会出安全性问题,结果却不是这样。
1.SQL注入
简单来说,SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。问题出现于集团对项目做的第一次安全检测,发现项目中有大量的接口被SQL注入攻击,这让我很吃惊,本以为使用了框架,不会犯这样比较低级的错误,但检查了下代码,漏洞的确很多。解决方案主要是使用预编译的SQL语句,在Hibernate不要使用append直接拼接参数而是使用SqlQuery.setString等 类似方法设置参数,Mybaitis中使用#而不是$,特别注意,在类似Select * From table where table_id in ('1', '2'); 这样的语句的时候,Mybaitis的Mapper.xml可以使用foreach关键字来循环添加in条件的数据,而不是在后台拼接好查询条件再用$。当然也有一些取巧的方法来应对SQL注入,比如写个工具类检查参数
/**
* 敏感词过滤工具
*/
public class SensitiveWordsUtil {
/** 查找注释符 和 单双引号 */
public static Pattern SQL_SENSITIVE_WORDS_PATTERN = Pattern.compile("--|\'|\"");
/**
* 检查字符串安全性是否能够拼凑成SQL
*
* @param string
* @return
*/
public static boolean findSQLSensitiveWords(String string) {
if (StringUtils.isBlank(string)) {
return false;
}
return SQL_SENSITIVE_WORDS_PATTERN.matcher(string.trim()).find();
}
}
附上其中一部分检测报告
2.XSS注入
XSS攻击全称跨站脚本攻击,攻击模式为利用漏洞将代码植入到提供给其它用户使用的页面中。简单来讲,你有一个注册页面需要填写用户的姓名年龄,有人恶意将姓名一栏填上<img src=x οnerrοr=alert('惊不惊喜!')>,后台管理人员在查看新增用户列表的时候就会弹出弹框。当然以上只是简单举例,如果你的接口暴露出去了,即攻击者绕过了前段检测,后端又没有相关检测的话,后果不堪设想,提供一个简单的Demo的前后端代码。这里涉及到HTML页面转义字符的知识,解决方法也比较简单,即不要偷懒增加后端的参数校验。
@Controller
@RequestMapping("test")
public class TestController {
@RequestMapping("testxss.do")
public String testXss(HttpServletRequest req, HttpServletResponse resp) {
// 可以分别放开注释看页面效果
// String xss = "<img src=x onerror=alert('xss')>";
// String xss = "<img src=x onerror=alert('xss')>";
req.setAttribute("xss", xss);
return "index";
}
}
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
System.out.println("basePath:" + basePath);
%>
<!DOCTYPE html><html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
show ${xss} : ${xss}
</body>
</html>
附上其中一部分检测报告
3.权限控制
我们系统的权限控制是由集团权限管理系统(PMS)统一控制的,在登陆时候,我们拉取登录用户的权限,但是PMS系统返回的数据仅仅包括用户可以看见的菜单列表,没有直接返回用户的角色数据,即比如权限比较低的用户登录系统只能看到客户列表,订单列表,基础数据列表等几个菜单栏,而超级管理员登录进来后则可以看到系统用户管理,权限分配等菜单。在这次检测中,集团安全组同事成功使用低权限用户访问高权限的页面,甚至某些按钮的URL,改变了系统数据。也就是说如果我们系统上线,比较关键的接口暴露出去了后果不堪设想。长久的解决方案当让是希望集团系统开放更多的数据给到我们,我们能够做到精准的权限控制。临时的解决方案是,增加一个权限过滤器,用户访问页面URL时候,认证该URL是否在他的权限数据里面,如果用户访问按钮URL(即数据接口),拿到HTTP头部的REFER字段,判定该请求来自哪个页面,再判定用户是否有该页面URL权限。
附上其中一部分检测报告