常见codeDEX问题及处理方案

Fortify工具介绍

Fortify静态代码分析器(SCA)通过以更少的工作量,更短的时间识别漏洞并保持代码质量,在帮助创建安全软件方面发挥着重要作用。Fortify SCA检测到其他静态测试技术无法比拟的广泛问题。Fortify软件安全研究组是一个全球团队,被业界公认为监控新兴威胁的顶级安全组织,他们的知识汇集到Fortify SCA(以及所有其他Fortify产品)中,因此组织可以掌握最新的威胁。

摘自官网:https://www.microfocus.com/en-us/products/static-code-analysis-sast/features

 

以下对一些容易出现的问题进行说明,在写代码的时候尽量一开始就避免此类错误。


日志类:

将未经验证的用户输入写入日志文件可致使攻击者伪造日志条目或将恶意信息内容注入日志。

1、Log Forging

ABSTRACT:将未经验证的用户输入写入日志文件可致使攻击者伪造日志条目或将恶意信息内容注入日志。
EXPLANATION
在以下情况下会发生 Log Forging 的漏洞:数据从一个不可信赖的数据源进入应用程序。
数据写入到应用程序或系统日志文件中。
Fix Suggestion:

  • 对输出到日志的不可信输入做白名单校验,或者黑名单校验(过滤各种换行符:\r,\n,\r\n)。
  • 对于是否为不可信数据,工具存在着识别上的误报,需要产品通过定制对应规则来消除误报。
  • 如果外部用户的输入不能直接或者间接更改日志内容的,可以判为误报。 在数据写入到日志前,将其进行URL编码(过滤掉特殊字符,尤其是换行符,换成%0D%0A),可以防止日志欺骗。

2、System Information Leak: Internal

ABSTRACT:揭示系统数据或调试信息有助于攻击者了解系统并制定攻击计划。
EXPLANATION:通过打印或日志功能将系统数据或调试信息发送到本地文件、控制台或屏幕时,就会发生内部信息泄露。

Fix Suggestion:

避免将系统内部信息输出到日志、控制台、外部文件等。

可以将catch中的 e.printStackTrace() 打印改为 LogUtils.e(e.toString()) 或者 LogUtils.e(e.getMessage()),得注意 LogUtils 方法中的打印出现 Log Forging 问题。

3、Poor Error Handling: Overly Broad Catch

ABSTRACT:catch 块可以处理的异常种类很多,但往往会由于过多的考虑不应该在此位置处理的各种问题或故障而困扰不已。
EXPLANATION:多个 catch 块看上去既难看又繁琐,但使用一个“简约”的 catch 块捕获高级别的异常类(如 Exception),可能会混淆那些需要特殊处理的异常,或是捕获了不应在程序中这一点捕获的异常。本质上,捕获范围过大的异常与“Java 分类定义异常”这一目的是相违背的。随着程序的增加而抛出新异常时,这种做法会十分危险。而新发生的异常类型也不会被注意到。

Fix Suggenstion

  • 只声明捕获代码块中可能抛出的精确类型已检查异常并做相应的处理,而不是粗粒度直接声明捕获较高抽象层次的异常,如直接声明捕获Exception。简言之,就是 只捕获需要抛出的异常,不要捕获过大的异常。

4.Dead Code: Expression is Always false

ABSTRACT:此表达式(或部分表达式)的计算结果始终为 false。
EXPLANATION:此表达式(或部分表达式)的计算结果始终为 false;程序可以按一种更为简单的方式重写。而其附近代码的出现可能是出于调试目的,或者可能没有与程序中的其他代码一同进行维护。该表达式还可能为我们指出方法中的错误所在。

Fix Suggenstion:

重新审视代码,是否写法不当,或者去修改或是删除未使用的代码,它不仅不能实现任何程序功能,还会带来额外的麻烦和维修负担。


5、Denial of Service: StringBuilder

ABSTRACT:将不受信任的数据附加到使用默认支持数组大小进行初始化的 StringBuilder 实例会导致 JVM 过度使用堆内存空间。
EXPLANATION:将用户控制的数据附加到使用默认支持字符数组大小 (16) 进行初始化的 StringBuilder 实例,会导致应用程序在调整基础数组的大小以适应用户数据时占用大量堆内存。每次新数据附加到 StringBuilder 实例时,它都会尝试使数据适应其支持字符数组。如果数据不合适,将会创建新的数组,大小为之前的两倍,而旧数组在进行回收之前,将继续留在堆中。此缺陷可被攻击者用于执行拒绝服务 (DoS) 攻击。

Fix Suggenstion:

使用大小与预期数据的长度相当的数组初始化 StringBuilder,以减少调整支持数组大小的次数。在将数据附加到 StringBuilder 实例前,检查数据大小。简言之,在初始化 StringBuilder 时,给它设置大小。

6、J2EE Bad Practices: Threads

ABSTRACT:禁止在某些环境下使用 Web 应用程序中的线程管理,因为此时使用线程管理非常容易出错。
EXPLANATION:J2EE 标准禁止在某些环境下使用 Web 应用程序中的线程管理,因为此时使用线程管理非常容易出错。线程管理起来很困难,并且可能还会以不可预知的方式干扰应用程序容器。即使容器没有受到干扰,线程管理通常还会导致各种难以发现的错误,如死锁、race condition 及其他同步错误等。

Fix Suggenstion:

用线程池管理线程,达到的效果是当web系统接收到大量的请求时,线程个数是可控的即可。
初始化 ThreadPoolExecutor,然后用 threadPoolExecutor.execute() 方法去执行线程。

7、Dead Code: Unused Method

ABSTRACT:此方法不能从该类以外的任何方法中获得。
EXPLANATION:不会调用这个方法,或者仅仅通过其他 dead code 进行调用。

Fix Suggenstion:

无用的方法,可以删除。

8、Code Correctness: Class Does Not Implement equals

ABSTRACT:在没有实现 equals() 的对象上调用了 equals() 方法。
EXPLANATION:当比较对象时,开发人员通常希望比较对象的属性。然而,在没有明确实现 equals() 的类(或任何超类/接口)上调用 equals() 会导致调用继承自 java.lang.Object 的 equals() 方法。Object.equals() 将比较两个对象实例,查看它们是否相同,而不是比较对象成员字段或其他属性。尽管可以合法地使用 Object.equals(),但这通常表示存在错误代码。

Fix Suggenstion:

在子类中对equals()方法进行重载。
验证 Object.equals() 的使用确实是您要调用的方法。如果不是,那么可实现 equals() 方法,或者使用其他方法来比较对象。

9、Insecure Randomness

ABSTRACT:标准的伪随机数值生成器不能抵挡各种加密攻击。
EXPLANATION:在对安全性要求较高的环境中,使用能够生成可预测值的函数作为随机数据源,会产生 Insecure Randomness 错误。电脑是一种具有确定性的机器,因此不可能产生真正的随机性。伪随机数生成器 (PRNG) 近似于随机算法,始于一个能计算后续数值的种子。
PRNG 包括两种类型:统计学的 PRNG 和密码学的 PRNG。统计学的 PRNG 可提供有用的统计资料,但其输出结果很容易预测,因此数据流容易复制。若安全性取决于生成数值的不可预测性,则此类型不适用。密码学的 PRNG 通过可产生较难预测的输出结果来应对这一问题。为保证值的加密安全性,必须使攻击者根本无法、或几乎不可能鉴别生成的随机值和真正的随机值。通常情况下,如果并未声明 PRNG 算法带有加密保护,那么它很可能就是统计学的 PRNG,因此不应在对安全性要求较高的环境中使用,否则会导致严重的漏洞(如易于猜测的密码、可预测的加密密钥、Session Hijacking 和 DNS Spoofing)。

Fix Suggenstion:

对于安全敏感的应用场景,应该使用强随机数:java.security.SecureRandom。
简言之,我们在使用随机数时,一般都是Random random = new Random(),我们应该换成强随机数SecureRandom。

10、Poor Style: Value Never Read

Fix Suggenstion:

变量赋值未被使用,直接删除不用变量,增加程序可读性。


11、Null Dereference

Fix Suggenstion:

程序可能会间接引用一个 null 指针,从而引起 null 指针异常。我们需要在使用一个变量之前应该判断其是否为Null。

12、NULL_RETURNS

Fix Suggenstion:

未检查函数返回值是否为空。在复引用之前,做好空指针判断。

13、Code Correctness: Constructor Invokes Overridable Function

ABSTRACT:类的构造函数调用了可被覆盖的函数。
EXPLANATION:如果构造函数调用了可覆盖的函数,则在该对象完全初始化之前,攻击者将可以访问 this 引用,进而导致出现漏洞。

Fix Suggenstion:

构造函数不应调用可覆盖的函数,无论是通过将该函数指定为 final,还是将该类指定为 final 的方式。或者,如果此代码仅在构造函数中才需要,则可使用访问说明符 private,或直接将逻辑放在子类的构造函数中。
Tips:出现这个问题,可能是我们在用说明符时用的 public ,将它改为 private 就行。

14、Code Correctness: Erroneous String Compare

ABSTRACT:进行字符串对比时,应采用 equals() 方法,而不是== 或 != 方法。
EXPLANATION:程序采用 == 或 != 来比较两个字符串是否相等,其实质比较的是两个对象,而不是字符串的值。因此,若采用这个方法,两个引用将永远不会相等。

Fix Suggenstion:

进行字符串对比时,应采用 equals() 方法,而不是 == 或 != 方法。
在使用 String 字符串做辨别时,也不要用 switch 方法去对比。应采用 if (…){…} else if(…){…}方法。

15、DIVIDE_BY_ZERO

Fix Suggenstion:

在进行除法或者取模运算时,请先判断除数是否为零。

16、FORWARD_NULL

Fix Suggenstion:

使用之前,先判断是否为null。

17、XML External Entity Injection

ABSTRACT:XML External Entities 攻击可利用能够在处理时动态构建文档的 XML 功能。
EXPLANATION:XML 实体可动态包含来自给定资源的数据。外部实体允许 XML 文档包含来自外部 URI 的数据。除非另行配置,否则外部实体会迫使 XML 解析器访问由 URI 指定的资源,例如位于本地计算机或远程系统上的某个文件。这一行为会将应用程序暴露给 XML External Entity (XXE) 攻击,从而用于拒绝本地系统的服务,获取对本地计算机上文件未经授权的访问权限,扫描远程计算机,并拒绝远程系统的服务。

Fix Suggenstion

  • 应对 XML 解析器进行安全配置,使它不允许将外部实体包含在传入的 XML 文档中。

为了避免 XXE injections,应为 XML 代理、解析器或读取器设置下面的属性:

factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);

如果不需要 inline DOCTYPE 声明,可使用以下属性将其完全禁用:

factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);

 

你可能感兴趣的:(Java,工具)