メソッドをオーバーライドあるいは隠蔽するときにアクセス範囲を広げてしまうと、悪意あるサブクラスが本来許可されていないメソッドにもアクセスできてしまう。ゆえに、プログラムは必要な場合にのみメソッドをオーバーライドし、可能な限りメソッドをfinal宣言することで、悪意あるサブクラス化を防止しなくてはならない。メソッドをfinal宣言できない場合、オーバーライドするメソッドのアクセス範囲をオーバーライドされるメソッドより広げてはいけない。
オーバーライドあるいは隠蔽するメソッドのアクセス修飾子は、オーバーライドあるいは隠蔽されるメソッドと少なくとも同程度のアクセス範囲を許すものでなければならない(Java言語仕様、§8.4.8.3、オーバーライドと隠蔽の必要条件[JLS 2005])。以下の表に、使用可能なアクセス修飾子を示す。
| オーバーライド/隠蔽されるメソッドの修飾子 | オーバーライド/隠蔽するメソッドの修飾子 |
|---|---|
| public | public |
| protected | protected か public |
| 指定なし | 指定なしか protected か public |
| private | オーバーライドできない |
違反コード
悪意あるサブクラスSubが、スーパクラスのdoLogic()メソッドをオーバーライドし、かつアクセス範囲を広げる様子を以下の違反コード例に示す。doLogic()はSubの親クラスSuperにおいてprotected宣言されているため、Subを使用するユーザは、doLogic()メソッドを呼び出すことができる。またクラスSubは、自身のdoLogic()メソッドをpublic宣言することで、アクセス範囲を広げている。
class Super {
protected void doLogic() {
System.out.println("Super invoked");
}
}
public class Sub extends Super {
public void doLogic() {
System.out.println("Sub invoked");
// センシティブな処理を行う
}
}
適合コード
以下の適合コードでは、doLogic()メソッドをfinal宣言し、悪意あるオーバーライドを防いでいる。
class Super {
protected final void doLogic() { // final 宣言する
System.out.println("Super invoked");
// センシティブな処理を行う
}
}
例外
MET04-EX0: java.lang.Cloneableインタフェースを実装するクラスでは、Object.clone()メソッドのアクセス範囲をprotectedからpublicに広げるべきである[SCG 2009]。
リスク評価
サブクラスを作成されることでアクセス制限が緩和され、アプリケーションのセキュリティを侵害される恐れがある。
| ルール | 深刻度 | 可能性 | 修正コスト | 優先度 | レベル |
|---|---|---|---|---|---|
| MET04-J | 中 | 中 | 中 | P8 | L2 |
自動検出
このルールの違反を検出するのは容易である。
関連ガイドライン
| MITRE CWE | CWE-487. Reliance on package-level scope |
| Secure Coding Guidelines for the Java Programming Language, Version 3.0 | Guideline 1-1. Limit the accessibility of classes, interfaces, methods, and fields |
参考文献
| [JLS 2005] | §8.4.8.3, Requirements in Overriding and Hiding |
翻訳元
これは以下のページを翻訳したものです。
MET04-J. Do not increase the accessibility of overridden or hidden methods (revision 99)



