【前言】
由于接触Java项目较多,本篇博客主要介绍Java项目代码审计中的数据输入输出。
【正文】
1.SQL注入
一般来说产生SQL注入漏洞的原因是由于系统前端交互界面中的数据未“净化”,造成SQL语句的拼接,产生风险。
在代码审计中优先查找Select语句,判断查询的参数是否是前端直接传过来的参数,如果未对该参数进行转义或者敏感字符字符过滤,那就存在风险点。
举个栗子:
public class SearchAction {
public String search(){
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = request.getSession();
String word = request.getParameter("searchWord");
SearchService search = new SearchService();
User user = search.findWorld(world);
if(user!=null){
request.setAttribute("user",user);
return "SUCCESS";
}
}
上述代码片段中的request.getParameter("searchWord");中的searchWorld参数是从前端获取的参数。
如果此参数未进行过滤,就会造成风险。
知识点:主流编程语言获取用户用户函数列表
2.跨站脚本攻击漏洞(XSS)
跨站脚本攻击是将恶意JavaScript代码插入到服务器界面,从而达到攻击目的。当用户访问HTML页面时,会触发插入的恶意代码,发生cookie窃取,账户劫持,拒绝服务攻击等风险。
跨站脚本攻击有以下攻击形式:
1.反射型跨站脚本攻击
攻击者利用社会工程学等手段,发送一个URL链接给用户打开,在用户打开页面的同时,浏览器会执行页面中嵌入的恶意脚本。
举个栗子:
<%out.print(request.getParameter("ceshi")); %>
通过请求参数获取的ceshi参数会直接在页面中输出,可导致反射型XSS漏洞。
2.存储型跨站脚本攻击
攻击者利用应用程序提供的录入或修改数据的功能,将数据存储到服务器或用户cookie中,当其他用户浏览展示该数据的页面时,浏览器会执行页面中嵌入的恶意脚本,所有浏览者都会受到攻击。
举个栗子:
while(rs.next()) {
%>
<tr>
<td><%=rs.getInt("id") %></td>
<td><%=rs.getString("ceshione")%></td>
<td><%=rs.getString("ceshitwo")%></td>
<td><%=rs.getString("ceshithree")%></td>
</tr>
<%
}
代码片段中变量id,ceshione.ceshitwo,ceshithree,均从数据库中获取的数据直接输出到页面,未进行任何安全过滤,会造成xss攻击。
3. DOM型跨站脚本攻击
由于HTML页面中,定义了一段JS,根据用户的输入,显示一段HTML代码,攻击者可以在输入时,插入一段恶意脚本,最终展示时,会执行恶意脚本。
DOM型跨站脚本攻击和以上两个跨站脚本攻击的区别是,DOM型跨站是纯页面脚本的输出,只有规范使用JavaScript,才可以防御。
<html>
<head>
<title>dom xss</title>
</head>
<body>
<script type=”text/javascript”>
var temp = document.URL;
var index = document.URL.indexOf(“content”)+8;
var par = temp.substring(index);
document.write(decodeURI(par));
</script>
</body>
</html>
DOM型本质在于利用可控参数拼接在DOM便签输出,利用触发事件造成弹窗。比如常见的payload:<img src=1 οnerrοr=alert(1)>
【安全规范】
1.SQL注入
防范SQL注入的方法很多,这里介绍较常见的几种安全编码。
(1)利用PreparedStatement对象中的set方法对参数进行赋值处理,参数化查询强制对每个参数进行预处理。这样就会对敏感字符进行转义处理。
String custname = request.getParameter("customerName");
String query = "SELECT account_balance FROM user_data WHERE user_name = ?";
PreparedStatement pstmt = connection.prepareStatement(query);
pstmt.setString(1, custname);
ResultSet results = pstmt.executeQuery();
(2)对输入的字符串进行合法性验证
合法性校验,简单的说就是检查输入的内容是否包含敏感字符,检查到非法字符后,对非法字符进行转义处理或者结束数据库查询返回警告信息。
常见的敏感字符包括但不限于:
’、”、<、>、/、*、;、+、-、&、|、(、)、and、or、select、union
注:合法性检验一定要写在服务端,否则防护无效。