使用Java语言编写安全的代码
之Struts2验证框架
记得前段时间读《Writing Secure Code》时候发现了这么一句话all input is Evil,想想挺有道理,尤其是Web程序,需要从页面上收集用户输入的数据,完成相关的业务逻辑,当这些输入没有做到相关的校验过滤,Web程序将存在漏洞,给恶意用户带来楔子口,恶意用户很可能对程序进行Sql注入、命令注入、跨站脚本、LDAP注入、代码注入、程序控制等相关攻击,参考OWASP 2010 T10注入漏洞攻击、跨站脚本漏洞攻击排在1、2名。因此,Web程序的数据验证很重要。
Web程序的输入验证一般分为客户端验证和服务器端验证,客户端验证主要采用纯JS代码或第三方框架实现,服务器端验证需要程序员开发相关的验证程序。一些初级程序员在开发的时候,往往只进行简单的客户端校验,认为通过客户端校验就可以避免恶意用户的攻击。实则不然,很多恶意的Hacker可以通过很多种方式(这里就不具体说什么方式了,以后相关的专题再细说)绕过客户端的验证,进入到服务器端,实施攻击。所以说,客户端校验对于恶意用户的恶意行为,是无能为力的。那将输入校验工作都放在服务器端好了,当然了,这样也不是很好,因为服务端校验代价比较高,大量的校验工作会增加服务器的负载。我认为一些针对用户误操作的校验放在客户端(如年龄输入框,用户不能输入超过200岁,除非它不是一般人或者不是人),而与安全、业务相关的校验放在服务器端,这样即降低了服务器的负载,又增强了Web程序的安全性。
我一直从事Java语言相关的开发工作和测试工作(说明一下,主要是源代码测试,漏洞测试、Fuzzing之类的是牛人在搞,哥不行,但是哥认为漏洞源于源代码,做好源代码测试,将不会产生漏洞,不给那些别有用心的人留有机会),这里我主要说说Java相关的输入校验,客户端校验的纯JS、第三方支持的JS框架(如Jquery)都比较简单,现在的美工妹妹都会搞了,这里就不说了。呀!是不是跑题了,我主要是想介绍一下Struts2的校验框架的,言归正传吧。
Struts2是一个MVC框架,提供了强大的数据校验功能。如何使用Struts2框架进行输入校验呢,主要采用两种方法:
1)在Action中重写ActionSupport的Validate(),Struts2执行Action的业务逻辑方法之前,先执行validate方法,进行输入验证,若验证没通过,返回input页面;验证通过,执行业务逻辑方法。
public class LoginAction extends ActionSupport{
private String username;
private String password;
//--getter and setter()方法省略 ---
public String execute() throws Exception{
//相应的业务逻辑,这里就是判断DB中有无该用户省略
}
@Override
public void validate() {
//做一些与安全相关的输入验证。如果你的领导在系统里面注册了“王二麻子”用户,你可以这样校验
if("王二麻子".equals(username.trim())){
this.addFieldError("username", "此系统不欢迎你!");
}
}
}
当然了,我们一般在一个Action中处理多个业务逻辑比较常见,只需将Validate方法改为ValidateXxxx(),如登录业务逻辑,改为ValidateLogin()就可以了,Action中不能少了相应的Login()方法,返回相应的String,就OK了。
2)利用Struts2提供的校验器或者自定义校验器,为每个Action编写检验规则文件。
Struts2的校验器定义在xwork-core-2.x.x\com\opensymphony\
xwork2\validator\validators\default.xml中,下面是两个校验器:
<validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
<validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
Struts2的校验规则名必须为<action名>--validation.xml或者是<action名>--方法名—validation.xml,与Action同一目录下。Struts2在执行Action的业务逻辑之前,将会加载这些XML进行输入校验。
下面是一个验证规则文件Demo
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<field name="username">
<field-validator type="requiredstring">
<message>用户名不能为空!</message>
</field-validator>
</field>
<field name="password">
</validators>
我工位边上一妹妹说,给规则文件搞个加密算法,加个密吧,更安全一些。我说:妹妹呀,你穿上马甲儿我认识你,Struts2不见得认识你。所以现在一些公司在开源项目的基础上,自己又添了一些东西进去,如安全方面、自身业务方面等等,别说了,又跑了,快到来水了。
采用Struts2做MVC框架,采用这种方式在一定程度上能够避免一些别有用心人的骚扰,如果有人问,针对某个字段我即在Action中重写了Validate()进行了校验,又在XML规则文件中进行了验证,会怎样,Struts2会先用XML的校验器检验,在用你自己在validate中编写的规则进行验证。可以看一下Struts2的源码楼一眼。
Struts2的相关校验器用法、自定义校验器等内容就先不说了。下回吧,我媳妇喊我回家吃饺子呢。