531 个项目已找到
弱点
Abstract
进行字符串对比时,应采用 equals() 方法,而不是==!= 方法。
Explanation
程序采用 ==!= 来比较两个字符串是否相等,其实质比较的是两个对象,而不是字符串的值。因此,若采用这个方法,两个引用将永远不会相等。

例 1:以下分支语句将永远不会被执行。


if (args[0] == STRING_CONSTANT) {
logger.info("miracle");
}


==!= 标记符被用来比较相同对象中包含的字符串时,它们只会按照预期的那样运行。要出现这种情况,最常用的方法就是将字符串内置,这样一来,就可以将字符串添加到一个由 String 类维护的对象池中。一旦字符串内置,在使用该字符串时,都会采用相同的对象,相等运算符也会按照预期的那样执行。所有字符串文字和带值的字符串常量都会自动内置。其他字符串可以通过调用 String.intern() 来手动内置,并会返回一个规范的当前字符串实例,必要时也会创建一个实例。
References
[1] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[2] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[3] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[4] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[5] Standards Mapping - Common Weakness Enumeration CWE ID 597
desc.structural.java.code_correctness_erroneous_string_compare
Abstract
变量被错误分配了零值。
Explanation
此字段被标注为 FortifyNonZero,表示不允许使用零值。
References
[1] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[2] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[3] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[4] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[5] Standards Mapping - Common Weakness Enumeration CWE ID 20
[6] Standards Mapping - Common Weakness Enumeration Top 25 2021 [4] CWE ID 020
[7] Standards Mapping - Common Weakness Enumeration Top 25 2022 [4] CWE ID 020
[8] Standards Mapping - Common Weakness Enumeration Top 25 2023 [6] CWE ID 020
[9] Standards Mapping - OWASP Application Security Verification Standard 4.0 5.1.3 Input Validation Requirements (L1 L2 L3), 5.1.4 Input Validation Requirements (L1 L2 L3)
[10] Standards Mapping - SANS Top 25 2009 Insecure Interaction - CWE ID 020
desc.structural.java.erroneous_zero_value_field
Abstract
静态方法不能被覆盖,但在作为实例方法调用时可能看起来是隐藏的。
Explanation
静态方法无法根据定义进行覆盖,因为它们属于类,而非类的实例。但是,某些情况下,静态方法看似已在子类中被覆盖,这样会产生混淆并导致调用错误版本的方法。

示例 1:以下示例尝试定义 API 以对用户进行身份验证。


class AccessLevel{
public static final int ROOT = 0;
//...
public static final int NONE = 9;
}
//...
class User {
private static int access;
public User(){
access = AccessLevel.ROOT;
}
public static int getAccessLevel(){
return access;
}
//...
}
class RegularUser extends User {
private static int access;
public RegularUser(){
access = AccessLevel.NONE;
}
public static int getAccessLevel(){
return access;
}
public static void escalatePrivilege(){
access = AccessLevel.ROOT;
}
//...
}
//...
class SecureArea {
//...
public static void doRestrictedOperation(User user){
if (user instanceof RegularUser){
if (user.getAccessLevel() == AccessLevel.ROOT){
System.out.println("doing a privileged operation");
}else{
throw new RuntimeException();
}
}
}
}


此代码看上去还是比较合规。但是,由于我们是针对 user 实例,而非 UserRegularUser 类来调用 getAccessLevel() 方法,这意味着此条件下将始终返回 true 且会执行该限制操作,即使使用了 instanceof 以便进入 if/else 块的此部分也是如此。
References
[1] MET07-J. Never declare a class method that hides a method declared in a superclass or superinterface CERT
[2] Java Language Specification Chapter 8. Classes Oracle
[3] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[4] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[5] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[6] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[7] Standards Mapping - Common Weakness Enumeration CWE ID 486
desc.structural.java.code_correctness_hidden_method
Abstract
在序列化方法上使用错误的方法签名可能导致永远不会调用该方法。
Explanation
代码正确性:当可序列化的类创建序列化或反序列化函数但未采用正确的签名时,会发生“可序列化的方法签名不正确”的问题:


private void writeObject(java.io.ObjectOutputStream out) throws IOException;
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;
private void readObjectNoData() throws ObjectStreamException;


未使用序列化所要求的方法签名会导致在序列化/反序列化过程中永远不会调用该方法,这意味着将无法完成序列化/反序列化,或意味着不可信赖的代码可以获取对象的访问权限。
如果存在未抛出的异常,则可能意味着序列化/反序列化将失败并使应用程序崩溃,甚或可能悄然失败,以致构造的对象只是部分正确,从而导致出现极难调试的缺陷。调用程序应捕获这些异常,以便可以正确地处理错误的序列化/反序列化,而不会出现崩溃或部分构造的对象。
References
[1] SER01-J. Do not deviate from the proper signatures of serialization methods CERT
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 4
[4] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[5] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
desc.structural.java.code_correctness_incorrect_serializable_method_signature
Abstract
要正确使用 serialPersistentFields,必须将其声明为 privatestaticfinal
Explanation
Java 对象序列化规范 (Java Object Serialization Specification) 允许开发人员通过在 serialPersistentFields 数组中指定类的可序列化的字段来手动定义这些字段。仅当 serialPersistentFields 被声明为 privatestaticfinal 时,此功能才能运行。

例 1:将不会使用 serialPersistentFields 的下列声明来定义 Serializable 字段,因为它不是 privatestaticfinal

class List implements Serializable {
public ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("myField", List.class) };
...
}
References
[1] Sun Microsystems, Inc. Java Sun Tutorial
[2] SERIAL-2: Guard sensitive data during serialization Oracle
[3] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[4] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 5
[5] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[6] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[7] Standards Mapping - Common Weakness Enumeration CWE ID 485
desc.structural.java.code_correctness_incorrect_serialpersistentfields_modifier
Abstract
程序会调用数组上的 Object.equals(),而非 java.util.Arrays.equals().
Explanation
由于调用数组上的 Object.equals() 会检查数组地址是否相同而非检查数组元素是否相同,因此在大多数情况下这是一个错误调用,通常应将该代码替换为 java.util.Arrays.equals()

示例 1:以下示例尝试使用 Object.equals() 函数检查两个数组。


...
int[] arr1 = new int[10];
int[] arr2 = new int[10];
...
if (arr1.equals(arr2)){
//treat arrays as if identical elements
}
...


除非在某个点将一个数组分配至另一个数组,否则可能会始终生成一个从未执行的代码。
References
[1] EXP02-J. Do not use the Object.equals() method to compare two arrays CERT
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 5
[4] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[5] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[6] Standards Mapping - Common Weakness Enumeration CWE ID 398, CWE ID 754
[7] Standards Mapping - OWASP Application Security Verification Standard 4.0 11.1.7 Business Logic Security Requirements (L2 L3)
[8] Standards Mapping - SANS Top 25 2010 Risky Resource Management - CWE ID 754
desc.structural.java.code_correctness_call_to_object_equals
Abstract
这看上去好像能替代通用的 .NET 方法,但实际上达不到预想的效果。
Explanation
该方法的名称与通用的 .NET 方法相似,但它要么存在拼写错误,要么是参数列表导致其无法替代预期的方法。

例 1:以下方法的目的是重写 System.Object.Equals()


public boolean Equals(string obj) {
...
}


但是,由于 System.Object.Equals() 采用 object 类型的参数,因此永远不会调用该方法。
References
[1] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[2] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 2
[3] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[4] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[5] Standards Mapping - Common Weakness Enumeration CWE ID 398
desc.structural.dotnet.code_correctness_misleading_method_signature
Abstract
这看上去好像能替代通用的 Java 方法,但实际上并不能达到预想的效果。
Explanation
尽管该方法的名称与通用的 Java 方法相似,但它要么存在拼写错误,要么是参数列表导致其无法替代预期的方法。

例 1:以下方法的目的是重写 Object.equals()


public boolean equals(Object obj1, Object obj2) {
...
}


但是,由于 Object.equals() 只需要一个参数,因此永远不会调用Example 1 中的方法。
References
[1] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[2] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 2
[3] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[4] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[5] Standards Mapping - Common Weakness Enumeration CWE ID 398
desc.structural.java.code_correctness_misleading_method_signature