前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >华为大佬讲述应用安全防护ESAPI

华为大佬讲述应用安全防护ESAPI

作者头像
通信行业搬砖工
发布2024-02-22 08:09:18
1480
发布2024-02-22 08:09:18
举报
文章被收录于专栏:网络虚拟化网络虚拟化

摘要

ESAPI 是一个免费、开源的 web 应用程序安全控制库,使程序员更容易编写风险较低的应用程序。ESAPI库可以使程序员更容易对现有应用程序进行安全性改造,同时 ESAPI 库也是新应用系统开发确保安全的坚实基础。 ​

1. ESAPI 简介

OWASP Enterprise Security API (ESAPI)是一个免费、开源的web应用程序安全控制库,使程序员更容易编写风险较低的应用程序。ESAPI库旨在使程序员更容易对现有应用程序进行安全性改造。ESAPI库也是新开发的坚实基础。

考虑到特定语言的差异,所有OWASP ESAPI版本都有相同的基本设计:

  • 有一组安全控制接口。例如,定义了传递给安全控件类型的参数类型。
  • 每个安全控制都有一个参考实现。例如:基于字符串的输入验证。例如,Java 的 org.owasp.ESAPI.reference.FileBasedAuthenticator 的 ESAPI,而其他参考实现则是成熟的企业级参考实现,例如,org.oasp.ESAPI.reference.DefaultEncoder 或 org.owasp.ESAPI.reference.DefaultValidator。
  • 每个安全控件都有自己的实现(可选)。这些类中可能包含应用程序逻辑,这些逻辑可能由您的组织开发或为您的组织而开发。例如:企业身份验证。
  • 为使本项目尽可能易于传播并使更多人能够自由自用,本项目的源代码使用了 BSD 许可证。本项目的文档使用了知识共享署名许可证。你可以随意使用、修改ESAPI,甚至将它包含在商业产品中。

2. ESAPI 框架

  • OWASP ESAPI 已经实现下面安全控件
    • 身份认证
    • 访问控制
    • 输入验证
    • 输出编码/转义
    • 密码
    • 错误处理和日志
    • 通信安全
    • HTTP 安全
    • 安全配置
  • ESAPI 框架
  • ESAPI 覆盖的OWASP Top 10

3. ESAPI 的使用

3.1. ESAPI 在 pom.xml 中的配置

目前最新的版本是: 2.5.3.1, 可以直接在Maven 库中找到。

代码语言:javascript
复制
<!-- https://mvnrepository.com/artifact/org.owasp.esapi/esapi -->
<dependency>
  <groupId>org.owasp.esapi</groupId>
  <artifactId>esapi</artifactId>
  <version>2.5.3.1</version>
  <exclusions>
    <exclusion>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
    </exclusion>
  </exclusions>
</dependency>

<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.1.0</version>
  <scope>provided</scope>
</dependency>

3.2. 注入类问题的防护

网络安全问题很大一部分是由于注入类问题造成的。这类问题主要是由于对外部输入使用的过程中转码不当造成的,例如:SQL 注入、命令注入、跨站脚本等等。

Encode(编码器接口)包含了许多解码输入和编码输出的方法,这样处理过的字符对于各种解释器都是安全的。

3.2.1. 防护:XSS 跨站脚本攻击

  • HTML编码器(encodeForHTML)
代码语言:javascript
复制
@Test
void testEncodeForHTML() {
    String input = "<a href='sdfs'></a> < script > alert('xss'); </ script >";
    String encodedString = ESAPI.encoder().encodeForHTML(input);

    LOG.info("EncodeForHTML: {}", encodedString);
}
  • 输出:
代码语言:javascript
复制
EncodeForHTML: &lt;a href&#x3d;&#x27;xss&#x27;&gt;&lt;&#x2f;a&gt; &lt; script &gt; alert&#x28;&#x27;xss&#x27;&#x29;&#x3b; &lt;&#x2f; script &gt;
  • URL编码器(encodeForURL)
代码语言:javascript
复制
@Test
void testEncodeForURL() {
    String input = "/?callback=<script>alert('xss')</script>";
    String encodedString;
    try {
        encodedString = ESAPI.encoder().encodeForURL(input);
        LOG.info("EncodeForURL: {}", encodedString);
    } catch (EncodingException e) {
        fail("Should not get exception:" + e.getMessage());
    }
}
  • 输出:
代码语言:javascript
复制
EncodeForURL: %2F%3Fcallback%3D%3Cscript%3Ealert%28%27xss%27%29%3C%2Fscript%3E

3.2.2. 防护:SQL 注入

代码语言:javascript
复制
@Test
void testEncodeForSQL() {
    String userId = "tom' or '1=1'";
    String sql = "select * from user where user='"
            + ESAPI.encoder().encodeForSQL(new MySQLCodec(MySQLCodec.Mode.STANDARD), userId) + "'";

    LOG.info("sql = {}", sql);
}
  • 输出:
代码语言:javascript
复制
sql = select * from user where user='tom\' or \'1\=1\''

3.2.3. 防护:命令注入

代码语言:javascript
复制
@Test
void testEncodeForOS() {
    String input = "dir & dir /s";
    String cmd = ESAPI.encoder().encodeForOS(new WindowsCodec(), input);

    LOG.info("cmd = {}", cmd);
}
  • 输出:
代码语言:javascript
复制
cmd = dir^ ^&^ dir^ ^/s

3.3. 输入校验问题的防护

网络安全最大的威胁是外部输入,所以对外部输入的校验对应用安全起着最大的防护作用。

3.3.1. ESAPI的输入校验

ESAPI有一个输入校验配置: validation.properties 给出了常用的校验。

  • validation.properties
代码语言:javascript
复制
Validator.SafeString=^[.\\p{Alnum}\\p{Space}]{0,1024}$
Validator.Email=^[A-Za-z0-9._%'-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$
Validator.IPAddress=^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
Validator.URL=^(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\:\\'\\/\\\\\\+=&;%\\$#_]*)?$
Validator.CreditCard=^(\\d{4}[- ]?){3}\\d{4}$
Validator.SSN=^(?!000)([0-6]\\d{2}|7([0-6]\\d|7[012]))([ -]?)(?!00)\\d\\d\\3(?!0000)\\d{4}$
  • 校验接口
代码语言:javascript
复制
/**
  * 输入校验
  * 
  * @param context 校验内容
  * @param input 校验输入  
  * @param type 校验类型,对应到 validation.properties 中的类型
  * @param maxLength 输入字符最大长度校验
  * @param allowNull 输入字符Null值校验,false - 不允许;true - 允许
  * @return 校验失败返回 false,校验成功返回 true
  */
boolean ESAPI.validator().getValidInput(String context, String input, String type, int maxLength, boolean allowNull);
代码语言:javascript
复制
@Test
void testValidatorEmail() {
    String input = "xxxx.com";
    if (!ESAPI.validator().isValidInput("", input, "Email", 11, false)) {
        LOG.error("Email validate fail!");
    } else {
        LOG.info("Email is validate.");
    }
}
  • 输出:
代码语言:javascript
复制
Email validate fail!

4. ESAPI 使用和升级过程中常遇到的问题

4.1. ExceptionInInitializerError

造成的 org.owasp.esapi.reference.DefaultEncoder CTOR threw exception

代码语言:javascript
复制
org.owasp.esapi.errors.ConfigurationException: java.lang.reflect.InvocationTargetException Encoder class (org.owasp.esapi.reference.DefaultEncoder) CTOR threw exception.
 at org.owasp.esapi.util.ObjFactory.make(ObjFactory.java:129)
 at org.owasp.esapi.ESAPI.encoder(ESAPI.java:101)
 at com.test.esapi.EsapiTest.testUpdateJulietInfo_good(EsapiTest.java:19)
 at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
 at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.lang.reflect.InvocationTargetException

 at org.owasp.esapi.util.ObjFactory.make(ObjFactory.java:86)
 ... 71 more
Caused by: java.lang.ExceptionInInitializerError
 at java.base/java.lang.Class.forName0(Native Method)
 at java.base/java.lang.Class.forName(Class.java:375)
 at org.owasp.esapi.util.ObjFactory.loadClassByStringName(ObjFactory.java:158)
 at org.owasp.esapi.util.ObjFactory.make(ObjFactory.java:81)
 at org.owasp.esapi.ESAPI.logFactory(ESAPI.java:139)
 at org.owasp.esapi.ESAPI.getLogger(ESAPI.java:155)
 at org.owasp.esapi.reference.DefaultEncoder.(DefaultEncoder.java:85)
 at org.owasp.esapi.reference.DefaultEncoder.(DefaultEncoder.java:109)
 at org.owasp.esapi.reference.DefaultEncoder.getInstance(DefaultEncoder.java:68)
 ... 76 more
Caused by: org.owasp.esapi.errors.ConfigurationException: Unable to locate resource: esapi-java-logging.properties
 at org.owasp.esapi.logging.java.JavaLogFactory.readLoggerConfiguration(JavaLogFactory.java:128)
 at org.owasp.esapi.logging.java.JavaLogFactory.(JavaLogFactory.java:96)
 ... 85 more

这个是 ESAPI 升级到 2.5.0.0 之后的版本时,最常碰到的问题。

2.5.0.0 是 ESAPI 一个重要的变动版本,我们从版本变更信息中可以看到:

  • 此版本 ESAPI 全面放弃了被 Log4J 不断的漏洞困扰的 Log4J 的支持,转而使用 SLF4J。如果您的 ESAPI.Logger 属性设置为使用 Log4J,如果不更改它,将引发模糊的 Exceptions 或 Errors,通常为 ExceptionInInitializerError。
  • 对 AntiSamy 升级到了 1.7.0,并支持了 AntiSamy 自定义的 AntiSamy-sapi.xml 文件。
  • 从上一个版本开始,此版本仅支持 Java 8 或更高版本。

从这里可以看到 ExceptionInInitializerError 应该是变更日志组件造成的,熟悉的朋友会立刻想到 ESAPI 的配置文件 ESAPI.properties 里面给出所有组件的配置。

从图中 69 到 72 行可以看到,69 行的:

代码语言:javascript
复制
ESAPI.Logger=org.owasp.esapi.logging.java.JavaLogFactory

还是指向 org.owasp.esapi.logging.java.JavaLogFactory, 后面的注释也提醒我们需要修改成 71 行的:

代码语言:javascript
复制
ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory

修改后问题解决。

4.2. java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest

代码语言:javascript
复制
java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest
 at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
 at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3402)
 at java.base/java.lang.Class.getMethodsRecursive(Class.java:3543)
 at java.base/java.lang.Class.getMethod0(Class.java:3529)
 at java.base/java.lang.Class.getMethod(Class.java:2225)
 at org.owasp.esapi.util.ObjFactory.loadMethodByStringName(ObjFactory.java:196)
 at org.owasp.esapi.util.ObjFactory.findSingletonCreateMethod(ObjFactory.java:173)
 at org.owasp.esapi.util.ObjFactory.make(ObjFactory.java:84)
 at org.owasp.esapi.ESAPI.validator(ESAPI.java:192)
 at com.huawei.hwe.esapi.EsapiTest.testEsapi_encodeForURL(EsapiTest.java:23)
 at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
 at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

Caused by: java.lang.ClassNotFoundException: javax.servlet.http.HttpServletRequest
 at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
 at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
 at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
 ... 79 more

这个问题明显是缺少了依赖库。我们可以查看 Maven 库关于 ESAPI 的定义和依赖信息。 https://mvnrepository.com/artifact/org.owasp.esapi/esapi/2.5.3.1

  • 编译依赖
  • 运行依赖

从运行依赖可以看到需要:javax.servlet » javax.servlet-api 点开后面的版本号:3.1.0,就可以得到 javax.servlet-api 3.1.0 的 mvn 依赖配置,将这个配置加到工程的 pom.xml 文件中就可以了。

在 pom.xml 中加入 javax.servlet-api 配置后,问题解决。

代码语言:javascript
复制
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

文章转载自华为云社区,作者uncle_tom

文章链接:

https://bbs.huaweicloud.com/blogs/421526?utm_source=oschina&utm_medium=bbs-ex&utm_campaign=other&utm_content=content

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-02-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 通信行业搬砖工 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. ESAPI 简介
  • 2. ESAPI 框架
  • 3. ESAPI 的使用
    • 3.1. ESAPI 在 pom.xml 中的配置
      • 3.2. 注入类问题的防护
        • 3.2.1. 防护:XSS 跨站脚本攻击
        • 3.2.2. 防护:SQL 注入
        • 3.2.3. 防护:命令注入
      • 3.3. 输入校验问题的防护
        • 3.3.1. ESAPI的输入校验
    • 4. ESAPI 使用和升级过程中常遇到的问题
      • 4.1. ExceptionInInitializerError
        • 造成的 org.owasp.esapi.reference.DefaultEncoder CTOR threw exception
          • 4.2. java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest
          相关产品与服务
          多因子身份认证
          多因子身份认证(Multi-factor Authentication Service,MFAS)的目的是建立一个多层次的防御体系,通过结合两种或三种认证因子(基于记忆的/基于持有物的/基于生物特征的认证因子)验证访问者的身份,使系统或资源更加安全。攻击者即使破解单一因子(如口令、人脸),应用的安全依然可以得到保障。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档