계: Code Quality

코드 품질이 낮으면 예측할 수 없는 동작이 발생합니다. 사용자 입장에서는 사용 편의성이 떨어지는 것으로 나타나는 경우가 많습니다. 공격자에게는 예상치 못한 방법으로 시스템에 부담을 줄 수 있는 기회가 됩니다.

93 개 항목 찾음
취약점
Abstract
NaN 비교에서 항상 오류가 발생합니다.
Explanation
NaN과의 비교는 항상 false로 평가됩니다. 단, NaN은 순서가 지정되지 않으므로 != 연산자를 사용하는 경우에는 항상 true로 평가됩니다.

예제 1: 다음 코드는 변수가 NaN이 아님을 확인합니다.


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


이 코드는 resultNaN이 아님을 확인하려고 합니다. 그러나 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 - CIS Azure Kubernetes Service Benchmark 1
[5] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[6] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[7] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[8] Standards Mapping - Common Weakness Enumeration CWE ID 486
desc.structural.java.code_correctness_comparison_with_nan
Abstract
이 클래스의 생성자는 재정의할 수 있는 함수를 호출합니다.
Explanation
생성자가 오버라이드 가능 함수를 호출하면 공격자는 개체가 완전히 초기화되기 전에 this 참조에 접근할 수 있으므로 취약점이 발생할 수 있습니다.

예제 1: 다음 코드는 오버라이드 가능한 메서드를 호출합니다.


...
class User {
private String username;
private boolean valid;
public User(String username, String password){
this.username = username;
this.valid = validateUser(username, password);
}
public boolean validateUser(String username, String password){
//validate user is real and can authenticate
...
}
public final boolean isValid(){
return valid;
}
}
validateUser 함수와 클래스는 final이 아니므로 오버라이드할 수 있습니다. 그런 다음 이 함수를 오버라이드하는 하위 클래스로 변수를 초기화하면 validateUser 기능을 무시할 수 있습니다. 예:


...
class Attacker extends User{
public Attacker(String username, String password){
super(username, password);
}
public boolean validateUser(String username, String password){
return true;
}
}
...
class MainClass{
public static void main(String[] args){
User hacker = new Attacker("Evil", "Hacker");
if (hacker.isValid()){
System.out.println("Attack successful!");
}else{
System.out.println("Attack failed");
}
}
}
Example 1의 코드는 “Attack successful!”을 출력합니다. Attacker 클래스는 슈퍼클래스 User의 생성자에서 호출되는 validateUser() 함수를 오버라이드하고, Java는 생성자에서 호출되는 함수의 하위 클래스를 먼저 확인하기 때문입니다.
References
[1] MET05-J. Ensure that constructors do not call overridable methods CERT
[2] EXTEND-5: Limit the extensibility of classes and methods Oracle
[3] OBJECT-4: Prevent constructors from calling methods that can be overridden Oracle
[4] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[5] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 2
[6] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[7] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
desc.structural.java.code_correctness_constructor_invokes_overridable_function
Abstract
해당 클래스 이름을 기반으로 개체 유형을 결정하면 예상치 못한 동작이 나타나거나 공격자가 악성 클래스를 삽입할 수 있습니다.
Explanation
공격자는 프로그램이 악성 코드를 실행하도록 만들기 위해 의도적으로 클래스 이름을 복제할 수 있습니다. 이러한 이유로 클래스 이름은 좋은 형식 식별자가 아니며 지정된 개체에 대한 신뢰를 부여하는 기준으로 사용해서는 안 됩니다.

예제 1: 다음 코드에서는 inputReader 개체의 입력을 신뢰할지 여부를 해당 클래스 이름을 기준으로 결정합니다. 공격자가 악성 명령을 실행하는 inputReader의 구현을 제공할 수 있는 경우, 이 코드는 개체의 양성 버전과 악성 버전을 구별할 수 없습니다.


if (inputReader.GetType().FullName == "CompanyX.Transaction.Monetary")
{
processTransaction(inputReader);
}
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 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 - CIS Azure Kubernetes Service Benchmark 1
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[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 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 - CIS Azure Kubernetes Service Benchmark 1
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[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 486
desc.dataflow.kotlin.code_correctness_erroneous_class_compare
Abstract
필드에 음수 값이 잘못 할당되었습니다.
Explanation
이 필드는 FortifyNonNegative로 주석 추가되었으며 음수 값은 허용되지 않음을 나타내는 데 사용됩니다.
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_negative_value_field
Abstract
x = NULLx != NULL 식은 항상 false가 됩니다.
Explanation
PL/SQL에서, NULL의 값은 불명확합니다. 이는 무엇과도 같지 않으며 다른 NULL 값과도 같지 않습니다. 또한 null 값은 다른 값과도 같지 않습니다.

예제 1:다음 문은 항상 false가 됩니다.


checkNull BOOLEAN := x = NULL;
예제 2:다음 문은 항상 false가 됩니다.


checkNotNull BOOLEAN := x != NULL;
References
[1] Steven Feuerstein Oracle PL/SQL Best Practices O'Reilly
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[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 480
desc.structural.sql.code_correctness_erroneous_null_comparison_plsql
Abstract
문자열은 == 또는 !=이 아닌 equals() 메서드로 비교해야 합니다.
Explanation
이 프로그램은 문자열이 같은지 비교하기 위해 == 또는 !=을 사용하는데 이 연산자는 두 개체의 값이 아닌 참조를 비교합니다. 두 참조가 같지 않을 가능성이 큽니다.

예제 1: 다음 분기는 실행되지 않습니다.


if (args[0] == STRING_CONSTANT) {
logger.info("miracle");
}
==!= 연산자는 같은 개체에 포함된 문자열을 비교하도록 사용할 때에만 예상대로 작동합니다. 이를 위한 가장 일반적인 방법은 인턴(intern)된 문자열에 대한 것이고, 여기에서 이 문자열은 String 클래스에 의해 유지되는 개체의 풀에 추가할 수 있습니다. 한 번 문자열이 인턴(intern)되면, 모든 문자열 사용은 동일한 개체를 사용하고 같은 연산자가 예상대로 작동합니다. 모든 문자열 리터럴 및 문자열 값 상수는 자동으로 인턴(intern)됩니다. 다른 문자열은 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
변수에 0 값이 잘못 할당되었습니다.
Explanation
이 필드는 FortifyNonZero로 주석 추가되었으며 0은 허용된 값이 아님을 나타내는 데 사용됩니다.
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