接上篇博客(信息安全开发注意事项二)
2、 SQL注入漏洞
隐患:攻击者利用现有应用程序,将恶意的SQL命令注入后台数据库引擎执行
风险:攻击者利用SQL注入漏洞查看、修改或删除后台数据库条目和表,获取用户账户等重要信息,篡改网页内容,设置能完全接管主机。
恶意代码示例:
String query = “select * from items where owner =’” + username + “’and itemname=’” + itemName + “’”;
ResultSet rs = stmt.execute(query)
恶意查询代码:
Username = wiley 和itemName = name’ or ‘a’=’a
select * from items where owner=’name’ or ‘a’ =’a’;
措施1 使用参数化
String query =”select id from users where username=? and password =? ”;
stmt.setString(1,user);
stmt.setString(2,pass);
ResultSet set = stmt.executeQuery();
措施2 在服务器端对特殊字符(如“|”、“and“、”%”等)进行安全检查和过滤
示例代码:
SQL_Injdata = “’|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|--|”;
措施3 采用白名单
//使用正则表达式验证用户名
String username = request.getParameter(“username”);
If(validate.macthPattern(username,”^[a-zA-Z0-9]*$”)}
//用户名符合要求、继续执行
2、 跨站请求伪造漏洞
隐患:这是一种挟制终端用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法,攻击者通过伪造有效请求,迫使用户执行攻击者所选择的操作。
风险:攻击者利用该漏洞可以获取用户的数据和操作指令,甚至获取控制权限
某银行系统在执行用户转账时会提交如下URL请求:
http://bank.com/transfer.do?acct=BOB&amount=100 transfer.do根据URL中的acct和amount数据完成网银转账操作,在上述URL中将向BOB账户转账100元,整个后台处理黄总除了验证当前用户登录以外没有其他校验措施。
攻击者向用户发送邮件,其中包含如下链接:
<a href=”http://bank.com/transfer.do?acct=TOM&amount=10000>ViewmyPicture!</a>
当用户在该网银系统登录后访问上述URL将自动向TOM账户转账10000元
措施1:限制身份证Cookie的到期时间
session.invalidate();
//销毁对话
Response.getWriter().println(“<script language=\”JavaScript\” type=\”text/JavaScript\”>alert(\””+由于您长时间没有操作,您的登录已超时,请重新登录!+”\”);
window.close;
</script>:
措施2
执行重要业务之前,要求用户提交额外的信息,如输入口令或图形验证码
String input_code = request.getParameter(“validate_code”);//用户输入验证码
String right_code = (String)request.getSession().getAttribute(“validate_code”);
//存在于Session中的正确验证码
措施3:在会话处理中使用一次性令牌
//生成令牌
Public String getTokenCode(HttpServletRequest request){
String tokenCode = request.getSession.getId +Math.abs(new SecureRandom().nextLong());
Return tokenCode;
}
//客户端加入令牌
<form method=”transfer_money”>
<input type=”text” name=”from”/>
<input type=”text” name=”to”/>
<input type=”text” name=”amount”/>
<input type=”hidden” name=”secret” value=”<%=a_dynamic_value>”/>
</form>
//服务器端验证令牌
//获取令牌数据
String input_token = request.getParameter(“secret”);
//检查令牌是否合法
if(!input_token.equalsIgnoreCase(right_token)){
request.setAttribute(“MSG”,”令牌错误”);
return mapping.findForward(“fail”);
}
缓冲区溢出漏洞
隐患:在数据向缓冲区复制的过程中,由于没有注意缓冲区的边界,超出缓冲区容量数据填充到缓冲区时覆盖了与缓冲区相邻的其他数据,从而引出内存问题。
风险:攻击者利用缓冲区溢出漏洞修改内存中变量的值,劫持进程,执行恶意代码,最终获得控制权
Void func(char*char){
char buffer[256];
strcpy(buffer,str);
return;
}
//strcpy()函数,如果str的字符串长度大于buffer的长度,将会产生溢出问题
措施1 禁止采用不安全的函数或接口,如strcat、strcpy、strnact、strncypy、sprinty等
避免使用的函数 | 替代的安全版本(Unix) | 替代的安全版本(window) |
stract | strlcat | strncat_s |
strcpy | strlcpy | strcpy_s |
strncat | strlcat | strncat_s |
strncpy | strlcpy | strncpy_s |
sprint | snprintf | snprintf |
…… |
|
|
措施2 在进行拷贝时,提供拷贝数据的长度,并对长度进行检查
Void function(char* szName, DWORD cbName){
Char szBuff[MAX-NAME];
//复制并使用
If(cbName <Max-NANE)
Strncpy(szBuff,szName,MAX-NAME-1);
}
拒绝服务攻击漏洞
隐患:攻击者利用合理的服务请求占用过多的服务资源
风险:攻击者利用拒绝服务攻击漏洞,使产生的大量非法用户抢占应用程序资源,导致合理用户无法使用。
恶意代码:
Int userSleepTime =Integer.parseInt(useInput);
Thread.sleep(userSleepTime);
//以上代码允许用户指定线程进入休眠状态的时间。通过指定一个较长的时间段,攻击者便能无限期的阻碍线程。
措施:提高系统对合法用户客户端发送请求判断的正确率,同时在开发中采取有效手段,针对系统资源进行合适的分配。
Int userSleepTim = Integer.parseInt(userInput);
If(userSleepTime >=SLEEP_TIME && userSleepTime <=SLEEP_MAX){
Thread.sleep(userSleepTIme);
}else{
Throw new Exception(“Invalid sleep duration”);
}
//以上代码限制用户指定线程进入休眠的时间数值
恶意文件上传漏洞
隐患:用户上传文件时,程序未在服务器端检测上传文件大小、类型是否符合预期要求。
风险:攻击者可以利用该漏洞上传木马文件或可借此将恶意代码隐藏在不同扩展名的文件中,从而获取目标服务器的控制权限。
FomFile theFile = advertiseform.getFilePath();
String up_path = servlet.getServletContent().getRealPath(“/”);
If(theFile !=null){
String newFileName = this.FileWrite(theFile,up_path);
}
措施:严格对上传文件进行检查、比如文件类型、名称等,同时严格限制用户对已上传文件的操作权限。
if(“”.equals(filename)){
ActionMessages message = nerw ActionMessages();
messages.add(“file”,new ActionMessage(“文件名不能为空!”,false));
……
}
String[] fArray = filename.split (”\\.”);
if(fArray.length ==1){
ActionMessages messages= new ActionMessages();
messages.add(“file”,new ActionMessage(“文件格式无效!”,false));
}
……
}
if(!”xls”.equlasIngoreCase(fArray[fArray.count()-1])){
ActionMessages messages = new ActionMessages();
messages.add(“file”,new ActionMessage(“文件格式无效!”,false));
}