界: Code Quality

代码质量不佳会导致不可预测的行为。对于用户来说,通常表现为可用性差。对于攻击者来说,提供了以意外方式对系统施加压力的机会。

4 个项目已找到
弱点
Abstract
将字节数组转换为 String 会导致数据丢失。
Explanation
在将字节数组的数据转换为 String 后,没有说明适用字符集外的数据会发生何种变化。这会导致数据丢失,或者在需要二进制数据来确保执行正确的安全措施时,安全级别降低。

示例 1:以下代码将数据转换为字符串,以便创建散列值。


...
FileInputStream fis = new FileInputStream(myFile);
byte[] byteArr = byte[BUFSIZE];
...
int count = fis.read(byteArr);
...
String fileString = new String(byteArr);
String fileSHA256Hex = DigestUtils.sha256Hex(fileString);
// use fileSHA256Hex to validate file
...


如果文件的大小小于 BUFSIZE,只要 myFile 中的信息已编码为与默认字符集相同,此方式就会很有用。但是,如果使用不同的编码方式,或者为二进制文件,则信息将会丢失。进而导致生成的 SHA 散列值的可靠性降低,并且也将更容易产生冲突,在默认字符集外的数据由相同的值(如问号)表示时,尤其如此。
References
[1] STR03-J. Do not encode noncharacter data as a string CERT
[2] When 'EFBFBD' and Friends Come Knocking: Observations of Byte Array to String Conversions GDS Security
[3] Standards Mapping - Common Weakness Enumeration CWE ID 486
desc.semantic.java.code_correctness_byte_array_to_string_conversion
Abstract
NaN 进行对比始终是一个错误。
Explanation
如果与 NaN 进行比较,得出的计算结果将始终为 false!= 运算符是个例外,因为 NaN 未经排序,所以始终会得出 true 结果)。

示例 1:以下示例尝试验证变量并非为 NaN


...
if (result == Double.NaN){
//something went wrong
throw new RuntimeException("Something went wrong, NaN found");
}
...


这将尝试验证 result 并非 NaN,但是使用带有 NaN 的运算符 == 将始终得出 false 值,所以此检查将永远不会抛出异常。
References
[1] NUM07-J. Do not attempt comparisons with NaN CERT
[2] Java Language Specification Chapter 4. Types, Values, and Variables Oracle
[3] INJECT-9: Prevent injection of exceptional floating point values Oracle
[4] Standards Mapping - Common Weakness Enumeration CWE ID 486
desc.structural.java.code_correctness_comparison_with_nan
Abstract
根据对象的类名称确定对象类型会导致意外行为或致使攻击者注入恶意的类。
Explanation
攻击者可以故意复制类名称,使程序执行恶意代码。因此,类名称并非合适的类型标识符,且不应用作向给定对象授予信任的基础。

示例 1:以下代码根据 inputReader 对象的类名称确认是否信任该对象的输入。如果攻击者能够提供一种执行恶意命令的 inputReader 实现方式,则此代码将无法区分该对象是善意的还是恶意的。


if (inputReader.GetType().FullName == "CompanyX.Transaction.Monetary")
{
processTransaction(inputReader);
}
References
[1] Standards Mapping - Common Weakness Enumeration CWE ID 486
desc.dataflow.dotnet.code_correctness_erroneous_class_compare
Abstract
根据对象的类名称确定对象类型会导致意外行为或致使攻击者注入恶意的类。
Explanation
攻击者可以故意复制类名称,使程序执行恶意代码。因此,类名称并非合适的类型标识符,且不应用作向给定对象授予信任的基础。

示例 1:以下代码根据 inputReader 对象的类名称确认是否信任该对象的输入。如果攻击者能够提供一种执行恶意命令的 inputReader 实现方式,则此代码将无法区分该对象是善意的还是恶意的。


if (inputReader.getClass().getName().equals("com.example.TrustedClass")) {
input = inputReader.getInput();
...
}
References
[1] OBJ09-J. Compare classes and not class names CERT
[2] Standards Mapping - Common Weakness Enumeration CWE ID 486
desc.dataflow.java.code_correctness_erroneous_class_compare
Abstract
基于对象的类名称确定对象的类型可能会导致意外行为或允许攻击者注入恶意类。
Explanation
攻击者可以故意复制类名称,使程序执行恶意代码。因此,类名称并非合适的类型标识符,且不应用作向给定对象授予信任的基础。

示例 1:以下代码根据 inputReader 对象的类名称确认是否信任该对象的输入。如果攻击者能够提供一种执行恶意命令的 inputReader 实现方式,则此代码将无法区分该对象是善意的还是恶意的。


if (inputReader::class.qualifiedName == "com.example.TrustedClass") {
input = inputReader.getInput()
...
}
References
[1] OBJ09-J. Compare classes and not class names CERT
[2] Standards Mapping - Common Weakness Enumeration CWE ID 486
desc.dataflow.kotlin.code_correctness_erroneous_class_compare
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 - Common Weakness Enumeration CWE ID 486
desc.structural.java.code_correctness_hidden_method