界: Code Quality

コードの質が低いと、予測できない動作につながります。ユーザーの視点には、それがしばしば使い勝手の悪さとなって現れます。攻撃者にとっては、予期せぬ方法でシステムにストレスを与える機会となります。

Code Correctness: Constructor Invokes Overridable Function

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