界: Code Quality
コードの質が低いと、予測できない動作につながります。ユーザーの視点には、それがしばしば使い勝手の悪さとなって現れます。攻撃者にとっては、予期せぬ方法でシステムにストレスを与える機会となります。
Code Correctness: Constructor Invokes Overridable Function
Abstract
クラスのコンストラクターは、オーバーライド可能な関数を呼び出します。
Explanation
コンストラクターがオーバーライド可能な関数をコールするとき、オブジェクトが完全に初期化される前に攻撃者が
例 1: 次の例では、オーバーライドされる可能性のあるメソッドをコールしています。
関数
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
desc.structural.java.code_correctness_constructor_invokes_overridable_function