内容简介:ESAPI(Enterprise Security API)是一个免费开源的Web应用程序API,目的帮助开发者开发出更加安全的代码,并且它本身就很方便调用。根据下面的图,我将会介绍OWASP上10种类型的漏洞所对应的API使用方法,大概有十多个接口。相关API介绍可以查看官方文档:
ESAPI(Enterprise Security API)是一个免费开源的Web应用程序API,目的帮助开发者开发出更加安全的代码,并且它本身就很方便调用。
根据下面的图,我将会介绍OWASP上10种类型的漏洞所对应的API使用方法,大概有十多个接口。
相关API介绍可以查看官方文档: https://www.javadoc.io/doc/org.owasp.esapi/esapi/2.1.0
对应使用到的API方法(使用思维导图分类):
0x01. 安装ESAPI(Java语言)
安装ESAPI的过程
1.下载esapi (jar)
2. https://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API#tab=Downloads
3.将jar包和源码Download下来
4.下载Log4j (log4j-1.2.17.zip)(一定要导入这个jar包,没有会报错的!)
http://logging.apache.org/log4j/1.2/download.html
5.我使用的编辑器是IDEA:
5-1.)通过项目 Project Structure 导入esapi、log4j;
5-2.)创建Resources目录;
在Resources目录里面导入ESAPI.properties 、 validation.properties 两个配置文件。
i.
ii.注意Idea通过如下方式创建Resources目录:
5-3.)ESAPI.properties 、validation.properties 在哪?
i. 注意这两个配置文件就在下载的ESAPI for Java(source)里面。路径如下:
写测试代码,校验是否成功部署
a).Code:
import org.owasp.esapi.ESAPI;
public class Test {
public static void main(String[]args) {
String safe = ESAPI.encoder().encodeForHTML("<script>alert('xss')</script>");
System.out.println(safe);
}
}
b). 右键运行看到的效果:
如果是JavaEE项目
1.请将esapi 和 log4j jar包放置到WEB-INF下的lib目录里面:
0x02. 从XSS类漏洞开始
防治Cross Site Scripting类型的漏洞,ESAPI提供了两个相关接口 Encode、Validator。
Encode接口 Encode(编码器接口)包含了许多解码输入和编码输出的方法,这样处理过的字符对于各种解释器都是安全的。
ESAPI根据XSS问题的特征和产生的原因,提供了不同的接口,下面我们介绍各个编码器的使用和原理。
Encode接口针对XSS的预发是在输出编码上,根据你要输出到不同地方转换成不同的编码。不同地方有HTML、Javascript、URL、CSS等。
(需了解3种编码格式:URL编码、HTML编码、JavaScript编码)其思想是对特殊意义的字符必须进行编码,编码后不影响原来结构体。
列举ESAPI针对XSS漏洞的7个预防方法:
- 调用HTML编码器
Code:
String safe1 =ESAPI.encoder().encodeForHTML("data1");
System.out.println(safe1);
String safe2 = ESAPI.encoder().encodeForHTML("<script>alert('xss')</script>");
System.out.println(safe2);
Out:
个人总结:
这个编码器使用的是HTMLEntityCodec,编译原理是,如果是空格、字母或者数字就不进行编码;如果有特殊字符在HTML中有匹配的替代字符,就使用替代字符。
应用场景:
有需要输出用户输入的字符串、表单提交后的数据需要展示的场景都可以运用。下面用留言板作为案例。
Code:
从数据库中得到数据,解析展示到用户浏览器界面。
<body>
<table border=1>
<tr>
<th>留言人姓名</th>
<th>留言时间</th>
<th>留言标题</th>
<th>留言内容</th>
</tr>
<%
ArrayList<Message> al = new ArrayList();
al = (ArrayList) session.getAttribute("al");
if (al != null) {
Iterator it = al.iterator();
while (it.hasNext()) {
Message ms = (Message) it.next();
%>
<tr>
<td><%= new LoginDao().getName(ms.getId()) %></td>
<td><%= ms.getTime().toString() %></td>
<td><%= ms.getTitle() %></td>
<td> <%=ESAPI.encoder().encodeForHTML( ms.getMessage() ) %></td>
</tr>
<%
}
}
%>
</table>
</body>
输出效果:
这样即使用户输入了
- 调用HTML属性编码器
Code:
String safe1 =ESAPI.encoder().encodeForHTMLAttribute("data 1 2");
System.out.println(safe1);
String safe2 = ESAPI.encoder().encodeForHTMLAttribute("<script>alert('xss')</script>");
System.out.println(safe2);
Out:
个人总结:
HTML属性编码和HTML编码在实现原理上是一样的,唯一的不同点就是HTML属性编码不需要对空格进行编码。所以也就是免疫了一个空格而已。
- 调用JavaScript编码器
Code:
<script> var searchValue = <%=ESAPI.encoder().encoderForJavaScript(searchValue)%>; // ...... </script>
个人总结:
JavaScript编码器首先判断是不是免疫的字符,如果是免疫字符,就直接返回;如果是数字、字母也直接返回;如果是小于256的字符就使用\xHH的编码方式;如果是大于256的字符,就使用\uHHHHH的方式编码。
- 调用CSS编码器
Code:
String ESAPI.encoder().encoderForCSS(String);
个人总结:
ESAPI的CSS编码是通过反斜杠(\)加上十六进制数进行的编码。
- 调用URL编码器
Code:
String url = ESAPI.encoder().encodeForURL("/?callback=<script>alert('xss')</script>");
System.out.println(url);
String url2 = ESAPI.encoder().encodeForURL("/a/title");
System.out.println(url2);
Out:
%2F%3Fcallback%3D%3Cscript%3Ealert%28%27xss%27%29 %3C%2Fscript%3E %2Fa%2Ftitle
个人总结:
URL编码器先将字符串转换为UTF-8,然后对转换的字符串用%加上十六进制数的方式编码。
7.调用复合(嵌套)编码器
Code:
<script>
var vDiv= document.createElement('div');
vDiv.innerHTML ="<%=ESAPI.encoder.encodeForJS(ESAPI.encoder.encodeForHTML(divVALUE))%>";
document.body.appendChild(vDiv);
</script>
个人总结:
上面那几种都只能处理一种编码的情况,对于存在多种编码的情况,可以使用复合(嵌套)编码,它根据由内到外的调用顺序来执行ESAPI的编码方法。
8.小结
由于Web页面上输出内容的地方很多,输出的背景环境也不相同,甚至有同一个输入可能输出到同一个页面上的不同地方,每一个地方的编码也可能不同,所以想彻底预防XSS是很困难的。从安全的角度考虑,建议使用HTTPOnly标志。
Validator接口
Validator接口定义了一组用于规范化和验证不可信输入的方法。开发人员可以扩展这个接口以适应自己的数据格式。与抛出异常相比,这个接口返回布尔结果,因为并非所有的验证问题都是安全问题。布尔返回允许开发人员更清晰地处理有效、无效的结果。
开发人员使用这个方法的时候必须采用“白名单”方法来验证特定的模式或字符集匹配。因为“黑名单”有可能被绕过。
1.调用getValidInput( )
Code:
// 1
getValidInput(java.lang.String context, java.lang.String input, java.lang.String type, int maxLength,boolean allowNull, ValidationErrorList errors);
// 2
isValidInput(java.lang.String context, java.lang.String input, java.lang.String type, int maxLength,boolean allowNull);
String validatedFirstName =ESAPI.validator().getValidInput("FirstName", myForm.getFirstName(), "FirstNameRegex", 255, false, errorList);
// 3
boolean isValidFirstName = ESAPI.validator().isValidInput("FirstName", myForm.getFirstName(), "FirstNameRegex", 255, false);
应用场景:
在有数据提交的地方,防止跨站攻击。 解决方案就是验证输入,检查每个输入的有效性。
Code:
String input = "<script>alert('xss')</script>";
String type = "SafeString"; //使用validation.properties文件定义的SafeString正则表达式规则
try {
String data = ESAPI.validator().getValidInput(
"Swingset Validation Secure Exercise", input, type,
200, false);
System.out.println(data);
} catch (ValidationException e) {
/*当检测到输入字符串不匹配正则表达式时产生该异常,应进行适当处理*/
input = "Validation attack detected";
request.setAttribute("userMessage", e.getUserMessage());
request.setAttribute("logMessage", e.getLogMessage());
} catch (Exception e) {
input = "exception thrown";
request.setAttribute("logMessage", e.getMessage());
}
返回规范化和验证过的输入数据。所有无效的输入将生成一个描述性的ValidationException异常。
0x03. 注入类漏洞
防治Injection Flaws类型的漏洞有多种类型比如有命令注入、XPath注入、LDAP注入、 SQL 注入、其它注入,我举例一个SQL注入的防护,而针对SQL注入ESAPI提供了一个相关接口Encode。
Encode接口
- 调用 ESAPI.Encoder().encodeForSQL()
Code:
//生成一个Oracle编码器实例 Codec ORACLE_CODEC = new OracleCodec(); //ESAPI 版本的查询 String query = "SELECT NAME FROM users WHERE id = " + ESAPI.encoder().encodeForSQL(ORACLE_CODEC, validatedUserId) + "AND date_created >= '" + ESAPI.encoder().encodeForSQL(ORACLE_CODEC, validatedStartDate) + "'"; //执行statement 获得结果 Statement myStmt = conn.createStatement(query);
个人总结:
可以看出使用ESAPI防范SQL注入非常容易,只需要创建一个相应的数据库编码器,然后在调用ESAPI.encoder().encodeForSQL时,作为第一个参数传入即可。 ESAPI也是封装好了过滤规则。
应用场景:
比如在搜索、查询场景下,需要用户输入的字符串插入SQL命令的地方,就可以运用。
0x04. 恶意文件执行类漏洞
防治Malicious File Execution类型的漏洞,ESAPI提供了一个相关接口 Validator。
Validator接口
使用ESAPI防治恶意文件执行漏洞有2个方法,1是使用ESAPI验证上传文件名。2是检查文件大小。
1.调用isValidFileName()
Code:
if(!ESAPI.validator().isValidFileName("upload",filename,
allowedExtensions,false)){
throw new Validation UploadException("Upload only simple filenames with
thefollowingextensions"+allowedExtensions,"Upload failed
isValidFileName check");
}
2. 使用ESAPI检查上传文件大小
Code:
ServletFileUpload upload=newServletFileUpload(factory);
0x05. 不安全的直接对象引用类漏洞
防治Insecure Direct Object Reference类型的漏洞,ESAPI提供了两个相关类AccessReferenceMap、AccessController。
AccessReferenceMap类
AccessReferenceMap是ESAPI提供的用户实现非直接引用ID和直接引用ID之间匹配的类。
- 实例化RandomAccessReferenceMap类
Code: //使用随机访问的引用map
AccessReferenceMapmap = new RandomAccessReferenceMap(); String userID =arm.getDirectReference(indirectRef);
应用场景:
在需要传递传递的访问中,比如用户访问信息页,通过UserID的操作。
AccessController接口
角色权限验证,检查当前用户对应的角色是否有权限访问url,权限的定义在esapi\fbac-policies\URLAccessRules.txt文件中。
- 调用assertAuthorizedForURL()
Code: ESAPI.accessController().assertAuthorizedForURL(); 0x06. CSRF类漏洞
防治Cross Site Request Forgery类型的漏洞,最常用的解决方案就是使用Token,在任何需要保护的表单,增加一个隐藏的字段来存放这个Token。对于需要保护的URL,需要增加一个参数来存放这个Token。ESAPI提供了一个相关接口 User。
User接口
管理身份验证和身份管理的规则接口。
调用resetCSRFToken()
使用流程:
a.新建CSRF令牌添加进用户每次登陆以及存储在http session里,这种令牌至少对每用户会话来说应该是唯一的,或者是对每个请求是唯一的。
//产生一个新的CSRF Token,在用户第一次登录的时候保存在用户的session中。
private String csrfToken = resetCSRFToken();
public String resetCSRFToken() {
csrfToken = ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS);
return csrfToken;
}
b.令牌同样可以包含在URL中或作为一个URL参数标记/隐藏字段。
c.在服务器端检查提交令牌与用户会话对象令牌是否匹 配。
d.在注销和会话超时,删除用户对象会话和会话销毁。
个人总结:
用ESAPI防止CSRF攻击的关键点就是生成Token,而且不能被攻击者知道生成方式,如果攻击者能伪造你的Token说明也是不安全的。还有CSRF安全的前提是你的站点没有XSS,不然攻击者利用XSS漏洞一样可以绕过CSRF检测。
应用场景:
在登录用户进行的操作里,都可以加上Token,比如用户提交修改密码操作。
0x07. 安全配置错误类漏洞
防治Leakage and Improper Error Handling类型的漏洞,需要具体项目具体分析。
Enterprise Security Exception
据不完全统计,国内个人信息泄露数达55.3亿条左右,平均每人就有4条相关的个人信息泄露,这些信息最终的命运,是在黑市中反复倒手,直至被榨干价值。其中,80%的数据泄露自企业内鬼,黑客仅占20%。
上面的信息说明(统计没有数据来源支持,不可全信),不过这类问题基本是内部自身的问题,得从内部开始查找、解决。
0x08. 失效的身份认证和会话管理类漏洞
无
0x09. 不安全的加密存储类漏洞
防治Insecure Cryptographic Storage类型的漏洞,ESAPI提供了一个相关接口 Encryptor。
Encryptor接口
Encryptor接口提供了一组用于执行通用加密、随机数和散列操作的方法。在配置文件ESAPI.properties中提供了关于加密的配置项,可以设置使用的加密算法、秘钥长度、初始化向量、哈希和签名算法。
- 调用encrypt()
Code:
//加密
- 调用decrypt ()
Code:
//解密
个人总结:
解密所提供的密文,使用来自它的信息和由属性Encryptor指定的主加密密钥。 0x10. 传输层保护不足类漏洞
防治Insecure Communications类型的漏洞,预防措施有三种:一、秘钥交换,二、对称加密与非对称加密结合,三、SSL、TLS。
0x11. 未限制URL访问类漏洞
防治Failure to Resstrict URL Access类型的漏洞,ESAPI提供了一个相关接口 AccessController。
AccessController接口
AccessController接口定义了一组方法,这些方法可以在各种应用程序中使用,以加强访问控制。如果这个URL不是公开的,那么必须限制能够访问他的授权用户,加强基于用户或角色的访问控制,完全禁止访问未被授权的页面类型(如配置文件、日志文件、源文件等)
- 调用assertAuthorizedForURL(Stringurl)
Codemode:
ESAPI.accessController().assertAuthorizedForURL(request.getRequestURI().toString());
个人总结:
该方法检查当前用户是否被授权访问引用的URL。通常该方法在应用程序的控制器或过滤器中调用。
以上所述就是小编给大家介绍的《ESAPI结合Top10安全开发实战》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 代理模式——结合SpringAOP讲解
- 如何结合 Scrum 和 Kanban
- NServiceBus 结合 RabbitMQ 使用教程
- ActiveMQ结合Spring收发消息
- quicklink学习以及结合React
- 业务流程与软件架构的结合
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Head First HTML and CSS
Elisabeth Robson、Eric Freeman / O'Reilly Media / 2012-9-8 / USD 39.99
Tired of reading HTML books that only make sense after you're an expert? Then it's about time you picked up Head First HTML and really learned HTML. You want to learn HTML so you can finally create th......一起来看看 《Head First HTML and CSS》 这本书的介绍吧!