それでは、実際に脆弱性のあるソースコードを見てみましょう。
以下のコードは、SSLを使用してサーバとの接続を確立する処理です。下記2つの問題があります。
-
SSL通信エラーを回避するために独自のTrustManagerを使用しています。
-
SSLExceptionを適切に処理していません。
このコードは、偽装サーバへの接続や中間者攻撃を検知できず、そのまま処理を継続してしまいます。
プロジェクト |
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;
}
}
|