サンプルアプリの脆弱性説明

具体的にどのような実装が脆弱性につながっているのか、ソースコードを確認してみましょう。

サンプルアプリのインポート

始めに、サンプルアプリをEclipseにインポートします。

「サンプルアプリをインポート」ボタンをクリックしてプロジェクトSSLConnectionをワークスペースにインポートしてください。

サンプルアプリをインポート

本サンプルアプリはソースコード参照用のため実行できません。

サンプルアプリの脆弱性

インポートしたサンプルプロジェクトに存在している脆弱性について詳しく説明します。

脆弱性のあるソースコード

プロジェクト SSLConnection
ソースファイル MainActivity.java
            try {

                //Private証明書をassetsから読み込み、検証
                KeyStore ks = KeyStoreUtil.getEmptyKeyStore();
                KeyStoreUtil.loadX509Certificate(ks,
                        mContext.getResources().getAssets().open("server.crt"));

                // ▼▼▼脆弱性のあるソースコード▼▼▼
                // 1.独自でTrustManagerを実装したクラス(PrivateSSLSocketFactory)を実装
                // 2.HostnameVerifierにSSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERをセット
                SSLSocketFactory sslSocketFactory = new PrivateSSLSocketFactory(ks);
                sslSocketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
                Scheme sch = new Scheme("https", sslSocketFactory, 443);
                // ▲▲▲脆弱性のあるソースコード▲▲▲

                client.getConnectionManager().getSchemeRegistry().register(sch);

                HttpGet request = new HttpGet(params[0]);

                HttpResponse response = client.execute(request);

                webView.loadData(EntityUtils.toString(response.getEntity()), "text/html", "UTF-8");
             // ▼▼▼脆弱性のあるソースコード▼▼▼
            } catch (Exception e) {

            }
            // ▲▲▲脆弱性のあるソースコード▲▲▲
            return null;
        }
    }
上記のコードはサンプルプロジェクト内のMainActivity#doInBackground(String... params)の一部です。 脆弱性の原因となっている処理は以下の2点です。
  • 独自のTrustManagerや HostnameVerifierの使用
    中間者攻撃を検知できなくなってしまう問題です。
    第三者認証局から発行されたサーバ証明書ではなく、私的に発行したプライベート証明書でHTTPS通信をする際、
    サーバ側で作成したプライベート認証局の不備が原因で、SSL通信エラーが発生することがあります。
    そのエラー回避するために、独自のTrustManagerや HostnameVerifierを使用した実装が行われています。 この例では、SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERを使用することにより、全てのホストを信用するように設定されています。
  • SSLExceptionを適切に処理していない
    中間者攻撃を検知できなくなってしまう問題です。
    セキュリティ例外を無視した場合、サーバ証明書に不備があること、攻撃者から中間者攻撃を受けていることを検知できなくなります。 この例では、例外をキャッチしても何も処理していません。例外を無視して処理を継続するように実装されています。

次は、脆弱性の修正方法について説明します。