界: 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 = NULL および x != 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
このプログラムは 2 つの文字列の比較に == または != を使用し、2 つのオブジェクトの値ではなく、オブジェクトが等価かどうかを比較します。このような場合、2 つの参照が等価でない可能性が高いのです。

例 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