内容简介: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
- 业务流程与软件架构的结合
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
数据结构C++语言描述
William Ford,William Topp / 刘卫东 沈官林 / 清华大学出版社 / 1999-09-01 / 58.00
一起来看看 《数据结构C++语言描述》 这本书的介绍吧!