SlideShare a Scribd company logo
Javaセキュアコーディングセミナー東京
第1回
オブジェクトの生成とセキュリティ


2012年9月9日(日)
JPCERTコーディネーションセンター
脆弱性解析チーム
久保 正樹,戸田 洋三




                  1
本資料について
本セミナーに使用するテキストの著作権はJPCERT/CCに帰属します。
事前の承諾を受けた場合を除いて、本資料に含有される内容(一部か全部か
を問わない)を複製・公開・送信・頒布・譲渡・貸与・使用許諾・転載・再
利用できません。



本セミナーに関するお問い合わせ
JPCERTコーディネーションセンター
セキュアコーディング担当
E-mail:secure-coding@jpcert.or.jp
TEL:03-3518-4600




                             2
自己紹介
‣ 久保 正樹(くぼ まさき)                  ‣ 戸田 洋三(とだ ようぞう)
  masaki.kubo@jpcert.or.jp         yozo.toda@jpcert.or.jp

‣ テクニカルリード、GSSP-Cプログラマ           ‣ リードアナリスト、GSSP-Cプログラマ
‣ 国立情報学研究所トップエスイープロジェク           ‣ 国立情報学研究所トップエスイープロジェク
  ト講師                              ト講師
‣ ISO/IEC SC27 WG4 エキスパート
                                 ‣ 小学生の頃に月刊『子供の科学』のマイコン
‣ プログラミングとの出会いは、コンピュータ             の記事でプログラミングに出会う。東京工業
  音楽から。前職はソニー(株)でVAIOのソ            大学情報理工学研究科にて型理論の研究で修
  フトウェア開発。退職後、ダートマス大学大             士。「証明からのプログラム抽出」に興味を
  学院で電子音響音楽修士。2005年から              持つ。千葉大学総合情報処理センターで学内
  JPCERTで情報セキュリティに従事。              ネットワーク運営やJP-MBoneの活動に従
                                   事した後、2001年からJPCERTのメン
‣ http://www.facebook.com/         バー。
  masaki.kubo
                                 ‣ http://www.facebook.com/yozo.toda




                             3
自己紹介
‣ 翻訳書
  ‣ 『Javaセキュアコーディング CERT/Oracle版』ASCII, 2012
  ‣ 『CERT C セキュアコーディングスタンダード』ASCII, 2009
  ‣ 『C/C++セキュアコーディング』ASCII, 2006




‣ セキュアコーディングに関する連載記事
  ‣ http://codezine.jp



                     4
このセミナーについて
‣ 4回連続
   ‣ 第1回 9月9日(日)
     ‣ オブジェクトの生成とセキュリティ
   ‣ 第2回 10月14日(日)
     ‣ 数値データの取扱いと入力値検査
   ‣ 第3回 11月11日(日)
     ‣ 入出力(ファイル,ストリーム)と例外時の動作
   ‣ 第4回 12月16日(日)
     ‣ メソッドに関するセキュリティ




                 5
今日の時間割
‣ 13:00 - 14:30   講義(担当:久保)

‣ 14:40 - 16:00   クイズと演習(担当:戸田)




                     6
Javaプログラマーとセキュリティ
‣ 暗号APIを正しく使ってますか?
‣ ウェブアプリの脆弱性って?
‣ 言語のセキュリティ機能、仕組みを理解していますか?
‣ セキュアコーディングを実践していますか?

‣ Javaの安全神話
   ‣ 「Javaは安全」とは、言語がその設計段階から安全性に配
     慮して設計されただけのこと
   ‣ コードが自動的に安全になるわけではない(なる部分もある)


‣ アプリのセキュリティは、プログラマの仕事!



                7
イントロダクション
基礎概念のおさらい




            8
JVMのメモリ構造
              スレッド1                     スレッド2

              PCレジスタ                    PCレジスタ



       push
                        pop
    現在のフレーム
                                               現在の
                                               フレーム

       フレーム

              JVMスタック                    JVMスタック


                          ヒープ
         オブジェクト                         オブジェクト           GCが管理する領域

                 オブジェクト


                        メソッドエリア
                              (.text)   ランタイムコンスタントプール



                               9
信頼できるコード vs. 信頼できないコード
‣ final宣言の意味


‣ セキュリティ上の脅威(どんな問題につながるから、何にどう
  気をつけなくてはならないのか)

‣ 攻撃者の視点からみると、何が見えるのか(どんな攻撃ができる
  のか)




               10
信頼境界 (trust boundary)
‣ プログラムに引かれた境界線
  ‣ 一方では、データは信頼できない
  ‣ 他方では、データは信頼できる(と想定)

‣ 信頼できない側から入ってきたデータは、検証にパスしてはじ
  めて、信頼できる側に移すことができる

‣ この線が不明確(あるいは未定義)だと、脆弱性につながる
 ‣ trust boundary violation

  usrname = request.getParameter(“usrname”);
  if (session.getAttribute(ATTR_USR) == NULL) {
    session.setAttribute(ATTR_USR, usrname);
  }


                              11
final宣言
‣ 変数がfinal


‣ クラスがfinal

‣ クラスのフィールドがfinal

‣ メソッドがfinal




                   12
クラスとクラスローダー
Javaを支える動的クラスローディング




            13
クラスファイル、型、クラスローダー

    D へのシンボリックな参                               •   バイトコード
                                               •   フィールドへのシンボリックな参照
  照は、Cのリンク時に実際の
                                               •   メソッド
     クラスに解決される                                 •   他のクラスの名前



class C {
  void f() {
    D d = new D();
    //...             コンパイル
  }
}
                 C.java    クラスファイル


                                                    ロードされる

                     クラスローダー
               ( クラスCの defining class loader)


                            14
動的クラスローディング
‣ Javaプラットフォームにおいて実行時にコンポーネントをイン
ストールする仕組みを実現する
 ‣ 遅延ロード (lazy loading)
   ‣ クラスは参照されて初めてロードされる
 ‣ ユーザ定義のクラスロードポリシー
   ‣ どのクラスを見つけるかカスタマイズ可能
 ‣ 複数の名前空間
   ‣ 同一のクラスが、異なるクラスローダーにロードされ、独
    立性をもつ




                      15
ブートストラップクラスローダー
‣ 卵が先か、ニワトリが先か
  ‣ クラスローダー自身もクラスのインスタンス
    ‣ 別のクラスによってロードされなくてはならない
 ‣ 最初のクラスローダーはどこからやってくる?

‣ ブートストラップクラスローダー
 ‣ java.* packages のようなコアクラスをロードする
 ‣ 「原始(primordial)」クラスローダーともよばれ、クラスロー
   ディングのプロセスの最初の引き金を引く




                  16
システムクラスローダー
‣ システムクラスローダー (アプリケーションクラスローダー)
 ‣ システムクラスをロードする
   ‣ CLASSPATH 配下に存在する全てのクラスはシステムクラ
    スと呼ばれる
 ‣ java.lang.ClassLoader.getSystemClassLoaderは
  システムクラスローダーを返す




                      17
クラスローダーの委譲階層
                                  親子関係
  ブートストラップクラスローダー
                                  定義関係


コアクラス        拡張クラスローダー


   拡張クラス            システムクラスローダー
                    (アプリケーションクラスローダー)



                           Java Network Launching
    システムクラス
                         Protocol (JNLP) クラスローダー
    (アプリケーションクラス)



           Java Web Start アプリケーションクラス

                    18
クラスローダーに関する制約
‣ クラスローダーはセンシティブな処理を行うことができる
  ‣ ex. クラスを定義する
‣ そのため、セキュリティマネージャーが存在する場合には制限が課される
  ‣ ClassLoader のコンストラクタはパーミッションが必要
    ‣ RuntimePermission - createClassLoader


‣ getSystemClassLoader()、getParent() 呼出しも同様に制限される
  ‣ どのオブジェクトも this.getClass().getClassLoader() を呼べ
   ば自身を定義したクラスローダーを取得できるので危険
  ‣ 呼出しに成功するのは…
    ‣ 呼出し側のクラスローダーが、実行コンテキストのクラスローダー
     と同じもしくその委譲元クラスローダーであるか、
    ‣ 実行コンテクストに RuntimePermission - getClassLoader
     がある場合
                          19
java.lang.ClassLoader
‣ クラスロード関連メソッド
 ‣ public Class loadClass(String name)
 ‣ protected native final Class findLoadedClass(String
   name)
 ‣ protected Class findClass(String name)
 ‣ protected final void resolveClass(Class c)
 ‣ protected Class<?> deineClass(String name, byte[] b,
   int off, int len)




                          20
loadClass(): クラスを探す

        ブートストラップクラスローダー                               loadClassメソッドの動作
(classNotFoundException)   loadClass               1.findLoadedClass()を呼んでクラスが
                                                   既にロードされていないかチェック
             クラスを定義するクラスローダー
                                                   2. 親のクラスローダーのloadClass()を

    findClass                    loadClass          呼ぶ(クラスのロードを親に委譲)
                                                   3. findClass()を呼んでクラスを探す(見
     探しているクラス              親のクラスローダー               つからなかったらClassNotFoundException)

                                       loadClass


                             Initiating クラスローダー




                                            21
クラス定義
‣ クラスは、バイナリ表現(クラスファイル)が見つかると、
defineClass()メソッドにより定義される
 ‣ クラスを表すバイト列をクラス Class’のインスタンスに変
  換し、デフォルトのProtectionDomainを新しくて定義さ
  れたクラスに割り当てる
  ‣ protected final Class defineClass(String name,
    byte[] b, int off, int len, ProtectionDomain
    protectionDomain)




         インスタンスの生成が可能

                        22
クラス名ではなくクラスを比較する




        23
クラスの同値
                      クラス名は同じ。でも別のクラス


定義ローダー                        定義ローダー


               ≠
  L1                            L2
          N              N

‣ C = <N, L>
   ‣ 実際のクラスの型は、クラス名 N とその定義ローダー L に
  よって一意に決まる



‣ JVM上の2つのクラス(クラス型)が同じであるとは
 ‣ クラス名が同じ
 ‣ かつ、それらの定義ローダーが同じ場合

                 24
クラス名ではなくクラスを比較
                                                                違反コード
// オブジェクト auth が期待するクラスのオブジェクトかどうかを調べる
if (auth.getClass().getName().equals
     ("com.application.auth.DefaultAuthenticationHandler")) {
   // ...
 }



‣ auth.getClass()
  ‣ このオブジェクトの実行時クラスを表すClassオブジェクト
   を返す
  ‣ getName()
     ‣ そのオブジェクトが表すクラス名




                                25
クラス名ではなくクラスを比較
                                                             適合コード
// オブジェクト auth が期待するクラスのオブジェクトかどうかを調べる
if (auth.getClass() ==
    com.application.auth.DefaultAuthenticationHandler.class) {
  // ...
}



‣ 右辺式で、ハンドラーのクラス名を直接指定
  ‣ このハンドラーがまだロードされていなければ、Javaの実行
    環境はクラスをロード
‣ クラスオブジェクト同士を比較




                                26
参考情報
‣ Inside Java 2 Platform Security, Second Edition


‣ Internals of Java Class Loading by Binildas
 Christudas
  ‣ http://onjava.com/pub/a/onjava/2005/01/26/classloading.html


‣ Java Security Guidelines: Developing and Using Java
  More Securely
  ‣ http://www.securingjava.com/chapter-seven/chapter-
    seven-1.html


‣ CWE-486: Comparison of Classes by Name
  ‣ http://cwe.mitre.org/data/definitions/486.html



                               27
オブジェクトの生成




        28
オブジェクトの生成方法
‣ 3つの方法
 ‣ new演算子
 ‣ clone()メソッド
 ‣ シリアライズからの復元

‣ それぞれについて、オーバーライド可能なメソッドを呼び出し
  た場合について考えてみる




                 29
オブジェクト生成時の注意
‣ オブジェクト生成時にオーバーライド可能なメソッドを呼び出
すと、初期化を完了していないデータが使用され、実行時例外
や予期せぬ結果を招く可能性がある。




‣ オブジェクト生成時にはオーバーライド可能なメソッドを呼び
出してはいけない!




              30
new演算子




         31
newによるオブジェクト生成の流れ

 ヒープメモリ領域確保


                    スーパークラスのコンストラ
 メンバフィールド初期化
                        クタ実行
   (デフォルト値)



  コンストラクタ実行         メンバフィールドに対応する
                    初期化子の評価結果を代入


  オブジェクト生成!
                    コンストラクタ本体を実行




               32
オブジェクト生成の流れ
                                                ColoredPointの領域確保
class Point {
  int x, y;                                  メンバフィールド初期化 (デフォルト値)
  Point() { x = 1; y = 1; }
}                                            ColoredPointのコンストラクタを実行
class ColoredPoint extends Point {
                                                      ColoredPoint() { super(); }
  int color = 0xFF00FF;
}
                                               Pointのコンストラクタを実行
class Test {
                                                   Point() { super(); x=1; y=1; }
  public static void main(String[] args) {
    ColoredPoint cp = new ColoredPoint();
    System.out.println(cp.color);              Objectのコンストラクタを実行
  }
                                                                        Object() { }
}

                                                 Pointの初期化式を評価

          cp                                  Pointのコンストラクタ本体を実行
                                                    (x = 1; y = 1;)

 x = 0
     1
                                              ColoredPointの初期化式を評価
 y = 0
     1
                                                  (color = 0xFF00FF;)
 color = 0
         0xFF00FF
                                             ColoredPointのコンストラクタ本体
                                    33
ポイント
‣ コンストラクタはまず、スーパークラスのコンストラクタを呼
  び出す
  ‣ スーパークラスのコンストラクタは、さらにスーパークラス
    のコンストラクタを呼び出す
   ‣ … Object class までさかのぼる …


‣ ここで問題

‣ スーパークラスのコンストラクタの中で、サブクラスでオー
  バーライドされたメソッドが呼び出されるとどうなる?




                    34
2つのdoLogic()

class SuperClass {
  public SuperClass (){ doLogic(); }
  public void doLogic(){ System.out.println("This is superclass!"); }
}

class SubClass extends SuperClass {
  private String color = null;
  public SubClass(){
    super();
    color = "Red";
  }
  public void doLogic(){
    System.out.println("This is subclass! The color is :" + color);
  }
}

public class Overridable {
  public static void main(String[] args){
    SuperClass bc = new SuperClass();
    SuperClass sc = new SubClass();
  }
}                          実行すると…
                           $ java Overridable
                           This is superclass!
                           This is subclass! The color is :null

                                    35
コンストラクタの実行
class SuperClass {
  public SuperClass (){ doLogic(); }
  public void doLogic(){ System.out.println("This is superclass!"); }
}

class SubClass extends SuperClass {
  private String color = null;
  public SubClass(){
    super();
    color = "Red";
  }
  public void doLogic(){
    System.out.println("This is subclass! The color is :" + color);
  }
}

public class Overridable {
  public static void main(String[] args){
    SuperClass bc = new SuperClass();
    SuperClass sc = new SubClass();
  }
}




                                    36
コンストラクタの実行
class SuperClass {
  public SuperClass (){ doLogic(); }
  public void doLogic(){ System.out.println("This is superclass!"); }
}

class SubClass extends SuperClass {
  private String color = null;
  public SubClass(){
    super();
    color = "Red";
  }
  public void doLogic(){
    System.out.println("This is subclass! The color is :" + color);
  }
}

public class Overridable {
  public static void main(String[] args){
    SuperClass bc = new SuperClass();
    SuperClass sc = new SubClass();
  }
}




                                    37
コンストラクタの実行
class SuperClass {
  public SuperClass (){ doLogic(); }
  public void doLogic(){ System.out.println("This is superclass!"); }
}

class SubClass extends SuperClass {
  private String color = null;
  public SubClass(){
    super();
    color = "Red";
  }
  public void doLogic(){
    System.out.println("This is subclass! The color is :" + color);
  }
}

public class Overridable {
  public static void main(String[] args){
    SuperClass bc = new SuperClass();
    SuperClass sc = new SubClass();
  }
}




                                    38
コンストラクタの実行
class SuperClass {
  public SuperClass (){ doLogic(); }
  public void doLogic(){ System.out.println("This is superclass!"); }
}

class SubClass extends SuperClass {
  private String color = null;
  public SubClass(){
    super();
    color = "Red";
  }
  public void doLogic(){
    System.out.println("This is subclass! The color is :" + color);
  }
}

public class Overridable {
  public static void main(String[] args){
    SuperClass bc = new SuperClass();
    SuperClass sc = new SubClass();
  }
}




                                    39
コンストラクタの実行
class SuperClass {
  public SuperClass (){ doLogic(); }
  public void doLogic(){ System.out.println("This is superclass!"); }
}

class SubClass extends SuperClass {     doLogic()はSubClassのコンスト
  private String color = null;
  public SubClass(){                    ラクタのコンテクストから呼び出され
    super();                            ている
    color = "Red";
  }
  public void doLogic(){
    System.out.println("This is subclass! The color is :" + color);
  }
}

public class Overridable {
  public static void main(String[] args){
    SuperClass bc = new SuperClass();
    SuperClass sc = new SubClass();
  }
}




                                    40
コンストラクタの実行
class SuperClass {
  public SuperClass (){ doLogic(); }
  public void doLogic(){ System.out.println("This is superclass!"); }
}

class SubClass extends SuperClass {
  private String color = null;
  public SubClass(){
    super();
    color = "Red";
  }
  public void doLogic(){
    System.out.println("This is subclass! The color is :" + color);
  }
}

public class Overridable {                   colorはまだ初期化が完了していな
  public static void main(String[] args){   いのに使用される
    SuperClass bc = new SuperClass();
    SuperClass sc = new SubClass();
  }
}
                            This is subclass! The color is :null




                                    41
コンストラクタの実行
class SuperClass {
  public SuperClass (){ doLogic(); }
  public void doLogic(){ System.out.println("This is superclass!"); }
}

class SubClass extends SuperClass {
  private String color = null;
  public SubClass(){
    super();
    color = "Red";
  }
  public void doLogic(){
    System.out.println("This is subclass! The color is :" + color);
  }
}

public class Overridable {
  public static void main(String[] args){
    SuperClass bc = new SuperClass();
    SuperClass sc = new SubClass();
  }
}




                                    42
言語仕様上の定義

  Javaでは,C++と違い,クラスのインスタンスを新たに生成し
  ている間 (ex.コンストラクタの実行中) のメソッドディスパッチ
  の規則について、(それ以外の場合とは)異なる規則を定めていな
  い。
  サブクラスでオーバーライドしたメソッドを,新たに作成するオ
  ブジェクトの初期化時に呼び出すと,たとえ初期化が完了する前
  であっても,オーバーライドしたメソッドが使用される.


                      JLS §12.5 新たなクラス・インスタンスの生成




                 43
セキュリティ上のリスク
‣ オーバライド可能なメソッドをコンストラクタで呼び出すと
  ‣ 初期化の完了していないデータが誤使用される
    ‣ 実行時例外、プログラムの予期せぬ動作

 ‣ オブジェクトの構築が完了する前にthis参照が外部に公開さ
   れてしまう
   ‣ 他のスレッドに初期化完了前の(矛盾した)データがみえ
    る(使用される)




               44
修正例
class SuperClass {
  public SuperClass (){ doLogic(); }
  public final void doLogic(){ System.out.println("This is superclass!"); }
}

class SubClass extends SuperClass {
  private String color = null;
  public SubClass(){
    super();
    color = "Red";
  }
  public void doLogic(){
    System.out.println("This is subclass! The color is :" + color);
  }
}

public class Overridable {
  public static void main(String[] args){
    qSuperClass bc = new SuperClass(); // print "this is superclass!"
    SuperClass sc = new SubClass(); // print "This is subclass!"
  }
}




‣ doLogic()をfinal宣言
 ‣ サブクラスでのオーバーライドはコンパイルエラーに

                                      45
参考情報
‣ MET05-J. コンストラクタにおいてオーバーライド可能なメソッドを呼
  び出さない
  ‣ http://www.jpcert.or.jp/java-rules/met05-j.htm


‣ ESA(European Space Agency)のJava Coding Standards
  ‣ Rule62: Do not call nonfinal method from within a constructor
     ‣ ftp://ftp.estec.esa.nl/pub/wm/anonymous/wme/bssc/Java-Coding-
       Standards-20050303-releaseA.pdf


‣ Secure Coding Guidelines for the Java Programming
  Language, Version 4.0
  ‣ Guideline 7-4: Prevent constructors from calling methods that can
    be overriden
     ‣ http://www.oracle.com/technetwork/java/seccodeguide-139067.html



                                  46
clone()メソッド




              47
clone()メソッド
‣ 特徴
  ‣ コンストラクタを呼ばずにオブジェクトを生成する手段
 ‣ Objectクラスで定義されている
 ‣ 「浅い」コピーを行う
 ‣ 必要なら深いコピーを行うようにオーバーライドして使う

 ‣ 参考: 『プログラミング言語Java第4版』 3.9 オブジェクトの複製




                   48
clone()メソッド
public class Object {
  ......
  protected Object clone() throws CloneNotSupportedException
  ......
}


    オブジェクトのコピーを作成して返します。… オブジェクトの「浅
    いコピー」を生成しますが、「深いコピー」は生成しません。



   このオブジェクトのクラスが Cloneable インタフェースを実装して
   いない場合は、CloneNotSupportedException がスローされます。


   Object クラス自体は、Cloneable インタフェースを実装しないため、クラス
   が Object である clone メソッドを呼び出すと、実行時に例外がスローされ
   ます。

                                      JavaSE6 API仕様、クラスObject, cloneメソッド
                             49
clone()メソッド

clone()からオーバーライド可能なメ
ソッドを呼び出すと危険!

‣ 悪意あるサブクラスがメソッドをオーバーライドして、
clone()の動作を操作
‣ 初期化途中のクローンオブジェクトにアクセスしてしまう




‣ クローン元とクローン先のオブジェクトが異なる(矛盾した)状
  態が発生しうる


                50
class SuperClass implements Cloneable {
  public SuperClass (){ doLogic(); }
  public void doLogic(){ System.out.println("This is superclass!"); }
  public Object clone() throws CloneNotSupportedException {
    final SuperClass clone = (SuperClass)super.clone();
    clone.doLogic();
    return clone;                                      3. doLogic()はスーパークラスで定義されているが、サブクラスの
  }                                                   コンテキストから呼び出されているため、結果的にサブクラスでオー
}             class SubClass extends SuperClass {               バーライドされたdoLogic()が呼び出される
                private String color = null;
                public SubClass(){
                  super();
                  color = "Red";
                }
                public void doLogic(){
                  System.out.println("This is subclass! The color is :" + color);
                }
                public Object clone() throws CloneNotSupportedException {
                  final SubClass clone = (SubClass)super.clone();
                  clone.color = “Blue”;
                  clone.doLogic();                             2. スーパークラスのclone()を実行
                  return clone;
                }
              }

public class CloneExample {
  public static void main(String[] args) throws CloneNotSupportedException {
    SuperClass bc = new SubClass();
    bc.clone();
  }
}                  1. サブクラスのclone()を実行


$ java cloneExample
This is subclass. The color is: null
This is subclass. The color is: Red                           問題のあるコード
                                                               実行すると…
This is subclass. The color is: Blue
                                                51
修正例

class SuperClass implements Cloneable {
  public SuperClass (){ doLogic(); }
  public final void doLogic(){ System.out.println("This is
superclass!"); }
  public Object clone() throws CloneNotSupportedException {
    final SuperClass clone = (SuperClass)super.clone();
    clone.doLogic();
    return clone;
  }
}



‣ doLogic()をfinal宣言
 ‣ オーバーライドを防止


‣ あるいはメソッドをprivate宣言


                            52
参考情報
‣ MET06-J. clone()からオーバーライド可能なメソッドを呼び
  出さない
  ‣ http://www.jpcert.or.jp/java-rules/met06-j.html


‣ 「Effective Java 第2版」
  ‣ 項目11 clone を注意してオーバーライドする




                                53
デシリアライズ
シリアライズしたオブジェクトの復元




           54
オブジェクトのシリアライズとデシリアライズ

           シリアライズ                        Java Object Serialization
                                      Specificationで仕様が規定されている
           writeObject()


Object               b y t e s t r e a m …

           readObject()
                                        書き出す
         復元 (デシリアライズ)




   改ざんされる可能性
                               ファイル                ソケット



                          55
シリアライズ:セキュリティ上の注意点
‣ オブジェクトのすべてのフィールド (privateフィールドも)が書
 き出される
 ‣ フィールドをprivate transient 宣言
 ‣ ObjectOutputStream.defaultWriteObjectではなく、ク
  ラス独自に実装したwriteObject/ writeExternal)を使う


‣ デシリアライズに使用されるストリームの改ざんやデータ破壊
  は、信頼できないオブジェクトのデシシリアライズにつながる
  ‣ バイト列は常に攻撃者に改ざんされていると想定したコーディ
    ングが求められる
  ‣ 特権コンテキストでデシリアライズしない



                     56
攻撃者に魅力あるJavaのプラットフォーム
‣ JRE = 普及率70%のOS
   ‣ プラットフォーム非依存のマルウェア、Webベースで攻撃
   ‣ 脆弱性の宝庫
   ‣ 昔のバージョンが使われ続ける




           2012年7月のデータ
          (www.statowl.com)




                       57
攻撃者に魅力あるJavaのプラットフォーム



        Javaはバックグラウンド
            で実行される



         Adobe PDFは目の前
            で実行される

            58
攻撃の流れ

                          攻撃者のサーバからマル
                          ウェアをダウンロード


                              被害者
 JRE         悪意あるア
                             のシステムで
              プレットを
の脆弱性                         アプレットを
             ウェブに公開
                               実行

サンドボックスを回避




       Write once, own everyone!
                 59
攻撃の実例
java.util.Calendarのデシリアライズ処理の脆弱性




               60
java.util.Calenderのデシリアライズの脆弱性
‣ The Java Runtime Environment (JRE) for Sun JDK and JRE 6
  Update 10 and earlier ... allows remote attackers to run
  untrusted applets and applications in a privileged context, as
  demonstrated by deserializing Calendar objects .
  (CVE-2008-5353)



                     リモートで攻撃


  カレンダーオブジェクトのデシリアライズ



信頼できないアプレット + 特権コンテキスト




                               61
脆弱な java.util.Calendar クラスの実装
public abstract class Calendar implements Serializable, Cloneable,
Comparable<Calendar> {

    /**
      * Reconstitutes this object from a stream (i.e., deserialize it).
      */
    private void readObject(ObjectInputStream stream)
!        throws IOException, ClassNotFoundException
    {
!        // ...
         // If there's a ZoneInfo object, use it for zone.
         ZoneInfo zi = null;
            try{
               ZoneInfo zi = (ZoneInfo) AccessController.doPrivileged(
                  new PrivilegedExceptionAction() {
"   "     "           public Object run() throws Exception {
"   "     "   "          return input.readObject();
"   "     "           }
"   "           });
"   "           if (zi != null) {
"   "               zone = zi;
"   "           }
!           } catch (Exception e) {}
      }


                                        62
攻撃メカニズム
‣ 以下、Donato Ferranteさんのマルウェア解説記事を元に、
  脆弱性悪用の仕組みを解説します
  ‣ http://www.inreverse.net/?p=804

‣ Java exploit kit malware: 3つのクラスファイルをふくむ
  jarファイル
   ‣ AppletX.java
   ‣ LoaderX.java
   ‣ PayloadX.java




                     63
AppletX.java




                            ステップ1



                    ステップ2




               64
細工された Serialized データ
ステップ1
                (実際は1939バイト)




        65
ステップ2

ステップ2




             PayloadXクラスのインス
                 タンスを作成
        66
data: マルウェアのダウンロード先を指す




        cc: ダウンロードするマルウェアの数




               ダウンロードして実行




   67
参考情報
‣ Security in Object Serialization
  ‣ http://docs.oracle.com/javase/6/docs/platform/serialization/spec/
    security.html
‣ Secure Coding Guidelines for the Java Programming
  Language, Version 4.0, 8 Serialization and Deserialization
  ‣ http://www.oracle.com/technetwork/java/seccodeguide-139067.html
‣ CWE-502: Deserialization of Untrusted Data
  ‣ http://cwe.mitre.org/data/definitions/502.html
‣ Write once, own everyone, Java deserialization issues
  ‣ http://blog.cr0.org/2009/05/write-once-own-everyone.html




                               68
サブクラスの依存性を保つ
The Fragile Base Class Problem




                   69
スーパークラスに変更を加える場合、
サブクラスの依存性を保つ
‣ スーパークラスに加えた変更が、サブクラスの動作に間接的に
  影響することがある

                         extends
 java.util.Hashtable
                       java.util.Properties         extends
       put()
                                   オーバーライド       java.security.Provider
      remove()

                                   オーバーライド               put()
     entrySet()

                                                       remove()

   JDK1.2で追加された         オーバーライドしてない!
                                                      entrySet()
(スーパークラスに対する変更)



                                         セキュリティチェックの未実
                                             装なentrySet()を継承


                                   70
The Fragile Base Class Problem
‣ クラス階層はデプロイ後に変更されないのが理想
  ‣ baseクラスへの小さな変更が、全体に大きな影響を与える
    リスク
  ‣ 最悪の場合、すべてのderivedクラスの修正、再コンパイ
    ル、再配布が必要

‣ 対策アプローチ
  ‣ Effective Java第2版、項目16 継承よりコンポジションを
    選ぶ
  ‣ Understand how a superclass can affect
    subclass behavior
   ‣ http://www.oracle.com/technetwork/java/seccodeguide-139067.html




                                    71
センシティブなデータは
ディフェンシブコピーする
OJB05-J.




           72
次のコードの問題は何?

class MutableClass {
  private Date[] date;

    public MutableClass() {
      date = new Date[20];
      for (int i = 0; i < date.length; i++) {
        date[i] = new Date();
      }
    }

    public Date[] getDate() {
      return date; // or return date.clone()
    }
}                          浅いコピーを返している!




                             73
修正例

class MutableClass {
  private Date[] date;

    public MutableClass() {
      date = new Date[20];
      for(int i = 0; i < date.length; i++) {
        date[i] = new Date();
      }
    }                             ディープコピーを作成し、返している

    public Date[] getDate() {
      Date[] dates = new Date[date.length];
      for (int i = 0; i < date.length; i++) {
        dates[i] = (Date) date[i].clone();
      }
      return dates;
    }
}
                             74
センシティブなデータはディフェンシブコピーする

‣ 浅いコピー(shallow copy)とは?
  ‣ Object.clone()は浅いコピーを返す
  ‣ プリミティブ型データはコピーする
  ‣ 参照型データは参照をコピーする。参照先のオブジェクトは
   コピーしない




                     75
実例:JDK1.7betaの脆弱性

public class InvalidityDateExtension extends Extension
implements CertAttrSet<String> {

    private Date date;                 クラス内の可変状態への参照
    ...
                                            を返していた!
    /**
      * Get the attribute value.
      */
    public Object get(String name) throws IOException {
       if (name.equalsIgnoreCase(DATE)) {
         return date;
       } else {
         throw new IOException
           ("Name not supported by InvalidityDateExtension");
       }
    }
}

                                src/share/classes/sun/security/x509/InvalidityDateExtension.java
                               76
修正されたコード

public Object get(String name) throws IOException {
  if (name.equalsIgnoreCase(DATE)) {
    if (date == null) {
      return null;
    } else {
      return (new Date(date.getTime()));    // クローン
      }
    } else {
      throw new IOException
        ("Name not supported by InvalidityDateExtension");
    }
}




                             77
オブジェクトに関するセキュリティ
‣ その他のセキュティ上の注意点についても知ろう!


‣ Java セキュアコーディングスタンダード
   ‣ オブジェクト(OBJ)
   ‣ http://www.jpcert.or.jp/java-rules/




                               78
Q&A




      79

More Related Content

What's hot (20)

PPTX
IBM JVM 소개 - Oracle JVM 과 비교
JungWoon Lee
 
PDF
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
日本マイクロソフト株式会社
 
PDF
Spring 5でSpring Testのここが変わる_公開版
Yuichi Hasegawa
 
PPTX
SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方
Hiroshi Tokumaru
 
PDF
ドメイン駆動設計の正しい歩き方
増田 亨
 
PPT
PHPのセッション管理にDynamoDBを使う
Taiji INOUE
 
PDF
JaSST '22 Tokyo - B5「テストの素人がゲーム品管組織を作って5年で感じた、QA業界のモヤモヤ」
Yoichi Kagamitani
 
PPTX
ドメイン駆動設計とマイクロサービス
kouki_mitsuishi
 
PPTX
Qlik Sense SaaSでソフトウェア開発ライフサイクルを活用
QlikPresalesJapan
 
PDF
Windowsフォームで大丈夫か?一番良いのを頼む。
Yuya Yamaki
 
PPTX
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.5.0対応)
fisuda
 
PPTX
Keycloak入門
Hiroyuki Wada
 
PPTX
TECH TALK 2021/08/10 一歩進んだQlikアプリの開発~Qlik専用QVDファイルでシステムの効率アップ
QlikPresalesJapan
 
PDF
AWS Black Belt Techシリーズ AWS Directory Service
Amazon Web Services Japan
 
PDF
Redmine + MySQL 応答性能の調査結果と対策
Kuniharu(州晴) AKAHANE(赤羽根)
 
PDF
20200303 AWS Black Belt Online Seminar AWS Cloud Development Kit (CDK)
Amazon Web Services Japan
 
PDF
Redmineのバージョンアップに追従していくための一工夫
Go Maeda
 
PDF
AWS Black Belt Online Seminar 2016 AWS CloudFormation
Amazon Web Services Japan
 
PPTX
はじめての datadog
Naoya Nakazawa
 
PPTX
Qlik Application Automation - ブロックで自動化処理をノーコード開発
QlikPresalesJapan
 
IBM JVM 소개 - Oracle JVM 과 비교
JungWoon Lee
 
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
日本マイクロソフト株式会社
 
Spring 5でSpring Testのここが変わる_公開版
Yuichi Hasegawa
 
SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方
Hiroshi Tokumaru
 
ドメイン駆動設計の正しい歩き方
増田 亨
 
PHPのセッション管理にDynamoDBを使う
Taiji INOUE
 
JaSST '22 Tokyo - B5「テストの素人がゲーム品管組織を作って5年で感じた、QA業界のモヤモヤ」
Yoichi Kagamitani
 
ドメイン駆動設計とマイクロサービス
kouki_mitsuishi
 
Qlik Sense SaaSでソフトウェア開発ライフサイクルを活用
QlikPresalesJapan
 
Windowsフォームで大丈夫か?一番良いのを頼む。
Yuya Yamaki
 
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.5.0対応)
fisuda
 
Keycloak入門
Hiroyuki Wada
 
TECH TALK 2021/08/10 一歩進んだQlikアプリの開発~Qlik専用QVDファイルでシステムの効率アップ
QlikPresalesJapan
 
AWS Black Belt Techシリーズ AWS Directory Service
Amazon Web Services Japan
 
Redmine + MySQL 応答性能の調査結果と対策
Kuniharu(州晴) AKAHANE(赤羽根)
 
20200303 AWS Black Belt Online Seminar AWS Cloud Development Kit (CDK)
Amazon Web Services Japan
 
Redmineのバージョンアップに追従していくための一工夫
Go Maeda
 
AWS Black Belt Online Seminar 2016 AWS CloudFormation
Amazon Web Services Japan
 
はじめての datadog
Naoya Nakazawa
 
Qlik Application Automation - ブロックで自動化処理をノーコード開発
QlikPresalesJapan
 

Similar to Javaセキュアコーディングセミナー東京第1回 講義 (20)

PPTX
Cve 2013-0422
abend_cve_9999_0001
 
PDF
静かに変わってきたクラスファイルを詳細に調べて楽しむ(JJUG CCC 2024 Fall講演資料)
NTT DATA Technology & Innovation
 
PDF
Javaセキュアコーディングセミナー東京第1回演習の解説
JPCERT Coordination Center
 
PDF
第1回内容の振り返り
skowata
 
PDF
Java/Androidセキュアコーディング
Masaki Kubo
 
PDF
[豆ナイト]Java small object programming
Yuichi Hasegawa
 
PPT
第1回java実習(helloworld)2011
デジタルシープラーニング
 
PPTX
pi-13. 今までの総まとめ
kunihikokaneko1
 
PDF
BOF1-Scala02.pdf
Hiroshi Ono
 
PDF
BOF1-Scala02.pdf
Hiroshi Ono
 
PDF
BOF1-Scala02.pdf
Hiroshi Ono
 
PDF
【LiT Leaders】Android0309
Ryo Yamamoto
 
PDF
Javaヂカラ #Java最新動向 -Java 11 の新機能やOracle Code One 2018 発の最新技術トレンドを一気にキャッチアップ-
PE-BANK
 
PDF
クラスローダーについて
Suguru ARAKAWA
 
PDF
Javaセキュアコーディングセミナー東京第4回講義
JPCERT Coordination Center
 
PDF
LITメンター研修_Android0212
Ryo Yamamoto
 
PDF
Java 7 invokedynamic の概要
Taku Miyakawa
 
PPTX
Xtend の紹介
Oda Shinsuke
 
KEY
関ジャバ JavaOne Tokyo 2012報告会
Koichi Sakata
 
PDF
Kink: invokedynamic on a prototype-based language
Taku Miyakawa
 
Cve 2013-0422
abend_cve_9999_0001
 
静かに変わってきたクラスファイルを詳細に調べて楽しむ(JJUG CCC 2024 Fall講演資料)
NTT DATA Technology & Innovation
 
Javaセキュアコーディングセミナー東京第1回演習の解説
JPCERT Coordination Center
 
第1回内容の振り返り
skowata
 
Java/Androidセキュアコーディング
Masaki Kubo
 
[豆ナイト]Java small object programming
Yuichi Hasegawa
 
第1回java実習(helloworld)2011
デジタルシープラーニング
 
pi-13. 今までの総まとめ
kunihikokaneko1
 
BOF1-Scala02.pdf
Hiroshi Ono
 
BOF1-Scala02.pdf
Hiroshi Ono
 
BOF1-Scala02.pdf
Hiroshi Ono
 
【LiT Leaders】Android0309
Ryo Yamamoto
 
Javaヂカラ #Java最新動向 -Java 11 の新機能やOracle Code One 2018 発の最新技術トレンドを一気にキャッチアップ-
PE-BANK
 
クラスローダーについて
Suguru ARAKAWA
 
Javaセキュアコーディングセミナー東京第4回講義
JPCERT Coordination Center
 
LITメンター研修_Android0212
Ryo Yamamoto
 
Java 7 invokedynamic の概要
Taku Miyakawa
 
Xtend の紹介
Oda Shinsuke
 
関ジャバ JavaOne Tokyo 2012報告会
Koichi Sakata
 
Kink: invokedynamic on a prototype-based language
Taku Miyakawa
 
Ad

More from JPCERT Coordination Center (20)

PDF
いま改めて製品開発者の脆弱性対応について考える ~情報セキュリティ早期警戒パートナーシップを運用する調整機関の視点から~
JPCERT Coordination Center
 
PDF
安全なプラグインに必要なこと: 脆弱性届出状況に見る傾向と対策 (WordCampTokyo 2017)
JPCERT Coordination Center
 
PDF
DLL読み込みの問題を読み解く
JPCERT Coordination Center
 
PDF
WordBench東京 7月勉強会「夏のLT大会!」『WordPress とバックアップの話』
JPCERT Coordination Center
 
PDF
CERT コーディングスタンダードご紹介 (OSC2017@Osaka)
JPCERT Coordination Center
 
PDF
脆弱性情報はこうしてやってくる
JPCERT Coordination Center
 
PDF
OWASP ASVS と Cheat Sheet シリーズ (日本語版) のご紹介 (OSC2016Hokkaido)
JPCERT Coordination Center
 
PPTX
Android Platform の URLConnection に HTTP ヘッダインジェクションの脆弱性
JPCERT Coordination Center
 
PDF
Case Studies and Lessons Learned from SSL/TLS Certificate Verification Vulner...
JPCERT Coordination Center
 
PDF
クロスサイトリクエストフォージェリ(CSRF)とその対策
JPCERT Coordination Center
 
PDF
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (JavaDayTokyo2015)
JPCERT Coordination Center
 
PDF
デブサミ2015 事例から学ぶAndroidアプリのセキュアコーディング「SSL/TLS証明書検証の現状と対策」
JPCERT Coordination Center
 
PDF
ソフトウェアセキュリティ保証成熟度モデル
JPCERT Coordination Center
 
PDF
Lessons (to be) Learned from Handling OpenSSL Vulnerabilities
JPCERT Coordination Center
 
PDF
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (KOF2014)
JPCERT Coordination Center
 
PDF
Android Secure Coding
JPCERT Coordination Center
 
PDF
JRE標準ライブラリの脆弱性事例を理解する (AtomicReferenceArrayクラス と Type Confusion)
JPCERT Coordination Center
 
PDF
Apache Axis2におけるXML署名検証不備
JPCERT Coordination Center
 
PDF
Apache Tomcat における クロスサイトリクエストフォージェリ (CSRF) 保護メカニズム回避の脆弱性
JPCERT Coordination Center
 
PDF
Spacewalkにおけるクロスサイト リクエストフォージェリ(CSRF)の脆弱性
JPCERT Coordination Center
 
いま改めて製品開発者の脆弱性対応について考える ~情報セキュリティ早期警戒パートナーシップを運用する調整機関の視点から~
JPCERT Coordination Center
 
安全なプラグインに必要なこと: 脆弱性届出状況に見る傾向と対策 (WordCampTokyo 2017)
JPCERT Coordination Center
 
DLL読み込みの問題を読み解く
JPCERT Coordination Center
 
WordBench東京 7月勉強会「夏のLT大会!」『WordPress とバックアップの話』
JPCERT Coordination Center
 
CERT コーディングスタンダードご紹介 (OSC2017@Osaka)
JPCERT Coordination Center
 
脆弱性情報はこうしてやってくる
JPCERT Coordination Center
 
OWASP ASVS と Cheat Sheet シリーズ (日本語版) のご紹介 (OSC2016Hokkaido)
JPCERT Coordination Center
 
Android Platform の URLConnection に HTTP ヘッダインジェクションの脆弱性
JPCERT Coordination Center
 
Case Studies and Lessons Learned from SSL/TLS Certificate Verification Vulner...
JPCERT Coordination Center
 
クロスサイトリクエストフォージェリ(CSRF)とその対策
JPCERT Coordination Center
 
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (JavaDayTokyo2015)
JPCERT Coordination Center
 
デブサミ2015 事例から学ぶAndroidアプリのセキュアコーディング「SSL/TLS証明書検証の現状と対策」
JPCERT Coordination Center
 
ソフトウェアセキュリティ保証成熟度モデル
JPCERT Coordination Center
 
Lessons (to be) Learned from Handling OpenSSL Vulnerabilities
JPCERT Coordination Center
 
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (KOF2014)
JPCERT Coordination Center
 
Android Secure Coding
JPCERT Coordination Center
 
JRE標準ライブラリの脆弱性事例を理解する (AtomicReferenceArrayクラス と Type Confusion)
JPCERT Coordination Center
 
Apache Axis2におけるXML署名検証不備
JPCERT Coordination Center
 
Apache Tomcat における クロスサイトリクエストフォージェリ (CSRF) 保護メカニズム回避の脆弱性
JPCERT Coordination Center
 
Spacewalkにおけるクロスサイト リクエストフォージェリ(CSRF)の脆弱性
JPCERT Coordination Center
 
Ad

Javaセキュアコーディングセミナー東京第1回 講義

  • 3. 自己紹介 ‣ 久保 正樹(くぼ まさき)        ‣ 戸田 洋三(とだ ようぞう) [email protected] [email protected] ‣ テクニカルリード、GSSP-Cプログラマ ‣ リードアナリスト、GSSP-Cプログラマ ‣ 国立情報学研究所トップエスイープロジェク ‣ 国立情報学研究所トップエスイープロジェク ト講師 ト講師 ‣ ISO/IEC SC27 WG4 エキスパート ‣ 小学生の頃に月刊『子供の科学』のマイコン ‣ プログラミングとの出会いは、コンピュータ の記事でプログラミングに出会う。東京工業 音楽から。前職はソニー(株)でVAIOのソ 大学情報理工学研究科にて型理論の研究で修 フトウェア開発。退職後、ダートマス大学大 士。「証明からのプログラム抽出」に興味を 学院で電子音響音楽修士。2005年から 持つ。千葉大学総合情報処理センターで学内 JPCERTで情報セキュリティに従事。 ネットワーク運営やJP-MBoneの活動に従 事した後、2001年からJPCERTのメン ‣ http://www.facebook.com/ バー。 masaki.kubo ‣ http://www.facebook.com/yozo.toda 3
  • 4. 自己紹介 ‣ 翻訳書 ‣ 『Javaセキュアコーディング CERT/Oracle版』ASCII, 2012 ‣ 『CERT C セキュアコーディングスタンダード』ASCII, 2009 ‣ 『C/C++セキュアコーディング』ASCII, 2006 ‣ セキュアコーディングに関する連載記事 ‣ http://codezine.jp 4
  • 5. このセミナーについて ‣ 4回連続 ‣ 第1回 9月9日(日) ‣ オブジェクトの生成とセキュリティ ‣ 第2回 10月14日(日) ‣ 数値データの取扱いと入力値検査 ‣ 第3回 11月11日(日) ‣ 入出力(ファイル,ストリーム)と例外時の動作 ‣ 第4回 12月16日(日) ‣ メソッドに関するセキュリティ 5
  • 6. 今日の時間割 ‣ 13:00 - 14:30 講義(担当:久保) ‣ 14:40 - 16:00 クイズと演習(担当:戸田) 6
  • 7. Javaプログラマーとセキュリティ ‣ 暗号APIを正しく使ってますか? ‣ ウェブアプリの脆弱性って? ‣ 言語のセキュリティ機能、仕組みを理解していますか? ‣ セキュアコーディングを実践していますか? ‣ Javaの安全神話 ‣ 「Javaは安全」とは、言語がその設計段階から安全性に配 慮して設計されただけのこと ‣ コードが自動的に安全になるわけではない(なる部分もある) ‣ アプリのセキュリティは、プログラマの仕事! 7
  • 9. JVMのメモリ構造 スレッド1 スレッド2 PCレジスタ PCレジスタ push pop 現在のフレーム 現在の フレーム フレーム JVMスタック JVMスタック ヒープ オブジェクト オブジェクト GCが管理する領域 オブジェクト メソッドエリア (.text) ランタイムコンスタントプール 9
  • 10. 信頼できるコード vs. 信頼できないコード ‣ final宣言の意味 ‣ セキュリティ上の脅威(どんな問題につながるから、何にどう 気をつけなくてはならないのか) ‣ 攻撃者の視点からみると、何が見えるのか(どんな攻撃ができる のか) 10
  • 11. 信頼境界 (trust boundary) ‣ プログラムに引かれた境界線 ‣ 一方では、データは信頼できない ‣ 他方では、データは信頼できる(と想定) ‣ 信頼できない側から入ってきたデータは、検証にパスしてはじ めて、信頼できる側に移すことができる ‣ この線が不明確(あるいは未定義)だと、脆弱性につながる ‣ trust boundary violation usrname = request.getParameter(“usrname”); if (session.getAttribute(ATTR_USR) == NULL) { session.setAttribute(ATTR_USR, usrname); } 11
  • 12. final宣言 ‣ 変数がfinal ‣ クラスがfinal ‣ クラスのフィールドがfinal ‣ メソッドがfinal 12
  • 14. クラスファイル、型、クラスローダー D へのシンボリックな参 • バイトコード • フィールドへのシンボリックな参照 照は、Cのリンク時に実際の • メソッド クラスに解決される • 他のクラスの名前 class C { void f() { D d = new D(); //... コンパイル } } C.java クラスファイル ロードされる クラスローダー ( クラスCの defining class loader) 14
  • 15. 動的クラスローディング ‣ Javaプラットフォームにおいて実行時にコンポーネントをイン ストールする仕組みを実現する ‣ 遅延ロード (lazy loading) ‣ クラスは参照されて初めてロードされる ‣ ユーザ定義のクラスロードポリシー ‣ どのクラスを見つけるかカスタマイズ可能 ‣ 複数の名前空間 ‣ 同一のクラスが、異なるクラスローダーにロードされ、独 立性をもつ 15
  • 16. ブートストラップクラスローダー ‣ 卵が先か、ニワトリが先か ‣ クラスローダー自身もクラスのインスタンス ‣ 別のクラスによってロードされなくてはならない ‣ 最初のクラスローダーはどこからやってくる? ‣ ブートストラップクラスローダー ‣ java.* packages のようなコアクラスをロードする ‣ 「原始(primordial)」クラスローダーともよばれ、クラスロー ディングのプロセスの最初の引き金を引く 16
  • 17. システムクラスローダー ‣ システムクラスローダー (アプリケーションクラスローダー) ‣ システムクラスをロードする ‣ CLASSPATH 配下に存在する全てのクラスはシステムクラ スと呼ばれる ‣ java.lang.ClassLoader.getSystemClassLoaderは システムクラスローダーを返す 17
  • 18. クラスローダーの委譲階層 親子関係 ブートストラップクラスローダー 定義関係 コアクラス 拡張クラスローダー 拡張クラス システムクラスローダー (アプリケーションクラスローダー) Java Network Launching システムクラス Protocol (JNLP) クラスローダー (アプリケーションクラス) Java Web Start アプリケーションクラス 18
  • 19. クラスローダーに関する制約 ‣ クラスローダーはセンシティブな処理を行うことができる ‣ ex. クラスを定義する ‣ そのため、セキュリティマネージャーが存在する場合には制限が課される ‣ ClassLoader のコンストラクタはパーミッションが必要 ‣ RuntimePermission - createClassLoader ‣ getSystemClassLoader()、getParent() 呼出しも同様に制限される ‣ どのオブジェクトも this.getClass().getClassLoader() を呼べ ば自身を定義したクラスローダーを取得できるので危険 ‣ 呼出しに成功するのは… ‣ 呼出し側のクラスローダーが、実行コンテキストのクラスローダー と同じもしくその委譲元クラスローダーであるか、 ‣ 実行コンテクストに RuntimePermission - getClassLoader がある場合 19
  • 20. java.lang.ClassLoader ‣ クラスロード関連メソッド ‣ public Class loadClass(String name) ‣ protected native final Class findLoadedClass(String name) ‣ protected Class findClass(String name) ‣ protected final void resolveClass(Class c) ‣ protected Class<?> deineClass(String name, byte[] b, int off, int len) 20
  • 21. loadClass(): クラスを探す ブートストラップクラスローダー loadClassメソッドの動作 (classNotFoundException) loadClass 1.findLoadedClass()を呼んでクラスが 既にロードされていないかチェック クラスを定義するクラスローダー 2. 親のクラスローダーのloadClass()を findClass loadClass 呼ぶ(クラスのロードを親に委譲) 3. findClass()を呼んでクラスを探す(見 探しているクラス 親のクラスローダー つからなかったらClassNotFoundException) loadClass Initiating クラスローダー 21
  • 22. クラス定義 ‣ クラスは、バイナリ表現(クラスファイル)が見つかると、 defineClass()メソッドにより定義される ‣ クラスを表すバイト列をクラス Class’のインスタンスに変 換し、デフォルトのProtectionDomainを新しくて定義さ れたクラスに割り当てる ‣ protected final Class defineClass(String name, byte[] b, int off, int len, ProtectionDomain protectionDomain) インスタンスの生成が可能 22
  • 24. クラスの同値 クラス名は同じ。でも別のクラス 定義ローダー 定義ローダー ≠ L1 L2 N N ‣ C = <N, L> ‣ 実際のクラスの型は、クラス名 N とその定義ローダー L に よって一意に決まる ‣ JVM上の2つのクラス(クラス型)が同じであるとは ‣ クラス名が同じ ‣ かつ、それらの定義ローダーが同じ場合 24
  • 25. クラス名ではなくクラスを比較 違反コード // オブジェクト auth が期待するクラスのオブジェクトかどうかを調べる if (auth.getClass().getName().equals ("com.application.auth.DefaultAuthenticationHandler")) { // ... } ‣ auth.getClass() ‣ このオブジェクトの実行時クラスを表すClassオブジェクト を返す ‣ getName() ‣ そのオブジェクトが表すクラス名 25
  • 26. クラス名ではなくクラスを比較 適合コード // オブジェクト auth が期待するクラスのオブジェクトかどうかを調べる if (auth.getClass() == com.application.auth.DefaultAuthenticationHandler.class) { // ... } ‣ 右辺式で、ハンドラーのクラス名を直接指定 ‣ このハンドラーがまだロードされていなければ、Javaの実行 環境はクラスをロード ‣ クラスオブジェクト同士を比較 26
  • 27. 参考情報 ‣ Inside Java 2 Platform Security, Second Edition ‣ Internals of Java Class Loading by Binildas Christudas ‣ http://onjava.com/pub/a/onjava/2005/01/26/classloading.html ‣ Java Security Guidelines: Developing and Using Java More Securely ‣ http://www.securingjava.com/chapter-seven/chapter- seven-1.html ‣ CWE-486: Comparison of Classes by Name ‣ http://cwe.mitre.org/data/definitions/486.html 27
  • 29. オブジェクトの生成方法 ‣ 3つの方法 ‣ new演算子 ‣ clone()メソッド ‣ シリアライズからの復元 ‣ それぞれについて、オーバーライド可能なメソッドを呼び出し た場合について考えてみる 29
  • 32. newによるオブジェクト生成の流れ ヒープメモリ領域確保 スーパークラスのコンストラ メンバフィールド初期化 クタ実行 (デフォルト値) コンストラクタ実行 メンバフィールドに対応する 初期化子の評価結果を代入 オブジェクト生成! コンストラクタ本体を実行 32
  • 33. オブジェクト生成の流れ ColoredPointの領域確保 class Point { int x, y; メンバフィールド初期化 (デフォルト値) Point() { x = 1; y = 1; } } ColoredPointのコンストラクタを実行 class ColoredPoint extends Point { ColoredPoint() { super(); } int color = 0xFF00FF; } Pointのコンストラクタを実行 class Test { Point() { super(); x=1; y=1; } public static void main(String[] args) { ColoredPoint cp = new ColoredPoint(); System.out.println(cp.color); Objectのコンストラクタを実行 } Object() { } } Pointの初期化式を評価 cp Pointのコンストラクタ本体を実行 (x = 1; y = 1;) x = 0 1 ColoredPointの初期化式を評価 y = 0 1 (color = 0xFF00FF;) color = 0 0xFF00FF ColoredPointのコンストラクタ本体 33
  • 34. ポイント ‣ コンストラクタはまず、スーパークラスのコンストラクタを呼 び出す ‣ スーパークラスのコンストラクタは、さらにスーパークラス のコンストラクタを呼び出す ‣ … Object class までさかのぼる … ‣ ここで問題 ‣ スーパークラスのコンストラクタの中で、サブクラスでオー バーライドされたメソッドが呼び出されるとどうなる? 34
  • 35. 2つのdoLogic() class SuperClass { public SuperClass (){ doLogic(); } public void doLogic(){ System.out.println("This is superclass!"); } } class SubClass extends SuperClass { private String color = null; public SubClass(){ super(); color = "Red"; } public void doLogic(){ System.out.println("This is subclass! The color is :" + color); } } public class Overridable { public static void main(String[] args){ SuperClass bc = new SuperClass(); SuperClass sc = new SubClass(); } } 実行すると… $ java Overridable This is superclass! This is subclass! The color is :null 35
  • 36. コンストラクタの実行 class SuperClass { public SuperClass (){ doLogic(); } public void doLogic(){ System.out.println("This is superclass!"); } } class SubClass extends SuperClass { private String color = null; public SubClass(){ super(); color = "Red"; } public void doLogic(){ System.out.println("This is subclass! The color is :" + color); } } public class Overridable { public static void main(String[] args){ SuperClass bc = new SuperClass(); SuperClass sc = new SubClass(); } } 36
  • 37. コンストラクタの実行 class SuperClass { public SuperClass (){ doLogic(); } public void doLogic(){ System.out.println("This is superclass!"); } } class SubClass extends SuperClass { private String color = null; public SubClass(){ super(); color = "Red"; } public void doLogic(){ System.out.println("This is subclass! The color is :" + color); } } public class Overridable { public static void main(String[] args){ SuperClass bc = new SuperClass(); SuperClass sc = new SubClass(); } } 37
  • 38. コンストラクタの実行 class SuperClass { public SuperClass (){ doLogic(); } public void doLogic(){ System.out.println("This is superclass!"); } } class SubClass extends SuperClass { private String color = null; public SubClass(){ super(); color = "Red"; } public void doLogic(){ System.out.println("This is subclass! The color is :" + color); } } public class Overridable { public static void main(String[] args){ SuperClass bc = new SuperClass(); SuperClass sc = new SubClass(); } } 38
  • 39. コンストラクタの実行 class SuperClass { public SuperClass (){ doLogic(); } public void doLogic(){ System.out.println("This is superclass!"); } } class SubClass extends SuperClass { private String color = null; public SubClass(){ super(); color = "Red"; } public void doLogic(){ System.out.println("This is subclass! The color is :" + color); } } public class Overridable { public static void main(String[] args){ SuperClass bc = new SuperClass(); SuperClass sc = new SubClass(); } } 39
  • 40. コンストラクタの実行 class SuperClass { public SuperClass (){ doLogic(); } public void doLogic(){ System.out.println("This is superclass!"); } } class SubClass extends SuperClass { doLogic()はSubClassのコンスト private String color = null; public SubClass(){ ラクタのコンテクストから呼び出され super(); ている color = "Red"; } public void doLogic(){ System.out.println("This is subclass! The color is :" + color); } } public class Overridable { public static void main(String[] args){ SuperClass bc = new SuperClass(); SuperClass sc = new SubClass(); } } 40
  • 41. コンストラクタの実行 class SuperClass { public SuperClass (){ doLogic(); } public void doLogic(){ System.out.println("This is superclass!"); } } class SubClass extends SuperClass { private String color = null; public SubClass(){ super(); color = "Red"; } public void doLogic(){ System.out.println("This is subclass! The color is :" + color); } } public class Overridable { colorはまだ初期化が完了していな public static void main(String[] args){ いのに使用される SuperClass bc = new SuperClass(); SuperClass sc = new SubClass(); } } This is subclass! The color is :null 41
  • 42. コンストラクタの実行 class SuperClass { public SuperClass (){ doLogic(); } public void doLogic(){ System.out.println("This is superclass!"); } } class SubClass extends SuperClass { private String color = null; public SubClass(){ super(); color = "Red"; } public void doLogic(){ System.out.println("This is subclass! The color is :" + color); } } public class Overridable { public static void main(String[] args){ SuperClass bc = new SuperClass(); SuperClass sc = new SubClass(); } } 42
  • 43. 言語仕様上の定義 Javaでは,C++と違い,クラスのインスタンスを新たに生成し ている間 (ex.コンストラクタの実行中) のメソッドディスパッチ の規則について、(それ以外の場合とは)異なる規則を定めていな い。 サブクラスでオーバーライドしたメソッドを,新たに作成するオ ブジェクトの初期化時に呼び出すと,たとえ初期化が完了する前 であっても,オーバーライドしたメソッドが使用される. JLS §12.5 新たなクラス・インスタンスの生成 43
  • 44. セキュリティ上のリスク ‣ オーバライド可能なメソッドをコンストラクタで呼び出すと ‣ 初期化の完了していないデータが誤使用される ‣ 実行時例外、プログラムの予期せぬ動作 ‣ オブジェクトの構築が完了する前にthis参照が外部に公開さ れてしまう ‣ 他のスレッドに初期化完了前の(矛盾した)データがみえ る(使用される) 44
  • 45. 修正例 class SuperClass { public SuperClass (){ doLogic(); } public final void doLogic(){ System.out.println("This is superclass!"); } } class SubClass extends SuperClass { private String color = null; public SubClass(){ super(); color = "Red"; } public void doLogic(){ System.out.println("This is subclass! The color is :" + color); } } public class Overridable { public static void main(String[] args){ qSuperClass bc = new SuperClass(); // print "this is superclass!" SuperClass sc = new SubClass(); // print "This is subclass!" } } ‣ doLogic()をfinal宣言 ‣ サブクラスでのオーバーライドはコンパイルエラーに 45
  • 46. 参考情報 ‣ MET05-J. コンストラクタにおいてオーバーライド可能なメソッドを呼 び出さない ‣ http://www.jpcert.or.jp/java-rules/met05-j.htm ‣ ESA(European Space Agency)のJava Coding Standards ‣ Rule62: Do not call nonfinal method from within a constructor ‣ ftp://ftp.estec.esa.nl/pub/wm/anonymous/wme/bssc/Java-Coding- Standards-20050303-releaseA.pdf ‣ Secure Coding Guidelines for the Java Programming Language, Version 4.0 ‣ Guideline 7-4: Prevent constructors from calling methods that can be overriden ‣ http://www.oracle.com/technetwork/java/seccodeguide-139067.html 46
  • 48. clone()メソッド ‣ 特徴 ‣ コンストラクタを呼ばずにオブジェクトを生成する手段 ‣ Objectクラスで定義されている ‣ 「浅い」コピーを行う ‣ 必要なら深いコピーを行うようにオーバーライドして使う ‣ 参考: 『プログラミング言語Java第4版』 3.9 オブジェクトの複製 48
  • 49. clone()メソッド public class Object { ...... protected Object clone() throws CloneNotSupportedException ...... } オブジェクトのコピーを作成して返します。… オブジェクトの「浅 いコピー」を生成しますが、「深いコピー」は生成しません。 このオブジェクトのクラスが Cloneable インタフェースを実装して いない場合は、CloneNotSupportedException がスローされます。 Object クラス自体は、Cloneable インタフェースを実装しないため、クラス が Object である clone メソッドを呼び出すと、実行時に例外がスローされ ます。 JavaSE6 API仕様、クラスObject, cloneメソッド 49
  • 51. class SuperClass implements Cloneable { public SuperClass (){ doLogic(); } public void doLogic(){ System.out.println("This is superclass!"); } public Object clone() throws CloneNotSupportedException { final SuperClass clone = (SuperClass)super.clone(); clone.doLogic(); return clone; 3. doLogic()はスーパークラスで定義されているが、サブクラスの } コンテキストから呼び出されているため、結果的にサブクラスでオー } class SubClass extends SuperClass { バーライドされたdoLogic()が呼び出される private String color = null; public SubClass(){ super(); color = "Red"; } public void doLogic(){ System.out.println("This is subclass! The color is :" + color); } public Object clone() throws CloneNotSupportedException { final SubClass clone = (SubClass)super.clone(); clone.color = “Blue”; clone.doLogic(); 2. スーパークラスのclone()を実行 return clone; } } public class CloneExample { public static void main(String[] args) throws CloneNotSupportedException { SuperClass bc = new SubClass(); bc.clone(); } } 1. サブクラスのclone()を実行 $ java cloneExample This is subclass. The color is: null This is subclass. The color is: Red 問題のあるコード 実行すると… This is subclass. The color is: Blue 51
  • 52. 修正例 class SuperClass implements Cloneable { public SuperClass (){ doLogic(); } public final void doLogic(){ System.out.println("This is superclass!"); } public Object clone() throws CloneNotSupportedException { final SuperClass clone = (SuperClass)super.clone(); clone.doLogic(); return clone; } } ‣ doLogic()をfinal宣言 ‣ オーバーライドを防止 ‣ あるいはメソッドをprivate宣言 52
  • 53. 参考情報 ‣ MET06-J. clone()からオーバーライド可能なメソッドを呼び 出さない ‣ http://www.jpcert.or.jp/java-rules/met06-j.html ‣ 「Effective Java 第2版」 ‣ 項目11 clone を注意してオーバーライドする 53
  • 55. オブジェクトのシリアライズとデシリアライズ シリアライズ Java Object Serialization Specificationで仕様が規定されている writeObject() Object b y t e s t r e a m … readObject() 書き出す 復元 (デシリアライズ) 改ざんされる可能性 ファイル ソケット 55
  • 56. シリアライズ:セキュリティ上の注意点 ‣ オブジェクトのすべてのフィールド (privateフィールドも)が書 き出される ‣ フィールドをprivate transient 宣言 ‣ ObjectOutputStream.defaultWriteObjectではなく、ク ラス独自に実装したwriteObject/ writeExternal)を使う ‣ デシリアライズに使用されるストリームの改ざんやデータ破壊 は、信頼できないオブジェクトのデシシリアライズにつながる ‣ バイト列は常に攻撃者に改ざんされていると想定したコーディ ングが求められる ‣ 特権コンテキストでデシリアライズしない 56
  • 57. 攻撃者に魅力あるJavaのプラットフォーム ‣ JRE = 普及率70%のOS ‣ プラットフォーム非依存のマルウェア、Webベースで攻撃 ‣ 脆弱性の宝庫 ‣ 昔のバージョンが使われ続ける 2012年7月のデータ (www.statowl.com) 57
  • 58. 攻撃者に魅力あるJavaのプラットフォーム Javaはバックグラウンド で実行される Adobe PDFは目の前 で実行される 58
  • 59. 攻撃の流れ 攻撃者のサーバからマル ウェアをダウンロード 被害者 JRE 悪意あるア のシステムで プレットを の脆弱性 アプレットを ウェブに公開 実行 サンドボックスを回避 Write once, own everyone! 59
  • 61. java.util.Calenderのデシリアライズの脆弱性 ‣ The Java Runtime Environment (JRE) for Sun JDK and JRE 6 Update 10 and earlier ... allows remote attackers to run untrusted applets and applications in a privileged context, as demonstrated by deserializing Calendar objects . (CVE-2008-5353) リモートで攻撃 カレンダーオブジェクトのデシリアライズ 信頼できないアプレット + 特権コンテキスト 61
  • 62. 脆弱な java.util.Calendar クラスの実装 public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> { /** * Reconstitutes this object from a stream (i.e., deserialize it). */ private void readObject(ObjectInputStream stream) ! throws IOException, ClassNotFoundException { ! // ... // If there's a ZoneInfo object, use it for zone. ZoneInfo zi = null; try{ ZoneInfo zi = (ZoneInfo) AccessController.doPrivileged( new PrivilegedExceptionAction() { " " " public Object run() throws Exception { " " " " return input.readObject(); " " " } " " }); " " if (zi != null) { " " zone = zi; " " } ! } catch (Exception e) {} } 62
  • 63. 攻撃メカニズム ‣ 以下、Donato Ferranteさんのマルウェア解説記事を元に、 脆弱性悪用の仕組みを解説します ‣ http://www.inreverse.net/?p=804 ‣ Java exploit kit malware: 3つのクラスファイルをふくむ jarファイル ‣ AppletX.java ‣ LoaderX.java ‣ PayloadX.java 63
  • 64. AppletX.java ステップ1 ステップ2 64
  • 66. ステップ2 ステップ2 PayloadXクラスのインス タンスを作成 66
  • 67. data: マルウェアのダウンロード先を指す cc: ダウンロードするマルウェアの数 ダウンロードして実行 67
  • 68. 参考情報 ‣ Security in Object Serialization ‣ http://docs.oracle.com/javase/6/docs/platform/serialization/spec/ security.html ‣ Secure Coding Guidelines for the Java Programming Language, Version 4.0, 8 Serialization and Deserialization ‣ http://www.oracle.com/technetwork/java/seccodeguide-139067.html ‣ CWE-502: Deserialization of Untrusted Data ‣ http://cwe.mitre.org/data/definitions/502.html ‣ Write once, own everyone, Java deserialization issues ‣ http://blog.cr0.org/2009/05/write-once-own-everyone.html 68
  • 70. スーパークラスに変更を加える場合、 サブクラスの依存性を保つ ‣ スーパークラスに加えた変更が、サブクラスの動作に間接的に 影響することがある extends java.util.Hashtable java.util.Properties extends put() オーバーライド java.security.Provider remove() オーバーライド put() entrySet() remove() JDK1.2で追加された オーバーライドしてない! entrySet() (スーパークラスに対する変更) セキュリティチェックの未実 装なentrySet()を継承 70
  • 71. The Fragile Base Class Problem ‣ クラス階層はデプロイ後に変更されないのが理想 ‣ baseクラスへの小さな変更が、全体に大きな影響を与える リスク ‣ 最悪の場合、すべてのderivedクラスの修正、再コンパイ ル、再配布が必要 ‣ 対策アプローチ ‣ Effective Java第2版、項目16 継承よりコンポジションを 選ぶ ‣ Understand how a superclass can affect subclass behavior ‣ http://www.oracle.com/technetwork/java/seccodeguide-139067.html 71
  • 73. 次のコードの問題は何? class MutableClass { private Date[] date; public MutableClass() { date = new Date[20]; for (int i = 0; i < date.length; i++) { date[i] = new Date(); } } public Date[] getDate() { return date; // or return date.clone() } } 浅いコピーを返している! 73
  • 74. 修正例 class MutableClass { private Date[] date; public MutableClass() { date = new Date[20]; for(int i = 0; i < date.length; i++) { date[i] = new Date(); } } ディープコピーを作成し、返している public Date[] getDate() { Date[] dates = new Date[date.length]; for (int i = 0; i < date.length; i++) { dates[i] = (Date) date[i].clone(); } return dates; } } 74
  • 75. センシティブなデータはディフェンシブコピーする ‣ 浅いコピー(shallow copy)とは? ‣ Object.clone()は浅いコピーを返す ‣ プリミティブ型データはコピーする ‣ 参照型データは参照をコピーする。参照先のオブジェクトは コピーしない 75
  • 76. 実例:JDK1.7betaの脆弱性 public class InvalidityDateExtension extends Extension implements CertAttrSet<String> { private Date date; クラス内の可変状態への参照 ... を返していた! /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(DATE)) { return date; } else { throw new IOException ("Name not supported by InvalidityDateExtension"); } } } src/share/classes/sun/security/x509/InvalidityDateExtension.java 76
  • 77. 修正されたコード public Object get(String name) throws IOException { if (name.equalsIgnoreCase(DATE)) { if (date == null) { return null; } else { return (new Date(date.getTime())); // クローン } } else { throw new IOException ("Name not supported by InvalidityDateExtension"); } } 77
  • 78. オブジェクトに関するセキュリティ ‣ その他のセキュティ上の注意点についても知ろう! ‣ Java セキュアコーディングスタンダード ‣ オブジェクト(OBJ) ‣ http://www.jpcert.or.jp/java-rules/ 78
  • 79. Q&A 79