こんにちは、nodaです。
先月、デブサミ(Developers Summit 2012)に参加してまいりました。
どのセッションも興味深く、大変有意義な時間を過ごさせていただきました。
なかでも今回は、久保正樹 氏のJava/Android セキュアコーディング入門で学んだことを紹介します。
内容はセッションのタイトル通り、Androidを開発する上でのセキュアコーディングについてです。
始めに久保氏はマルウェアについて言及し、モバイルマルウェアの63%がAndroid狙いであることについて提言していました。
モバイルアプリを取り巻くセキュリティ問題を語るうえでAndroidは切り離せないことになります。
そしてOWASPのTop10Risks(モバイルアプリ版)を挙げ、どこに脅威があるのか、どう対応・修正するかが問題であることを示唆すると同時に、過去の過ちが繰り返されていることを明言していました。
■繰り返される、過去の過ち
- 暗号化鍵のハードコーディング
- 乱数のエントロピー不足
- センシティブな情報の外部送信
- エラーメッセージにセンシティブな情報
上記の”過ち”をプログラマが知らない(知っているけど、コーディングできない)ことで、数年前のウェブアプリ脆弱性のデジャヴとなっているようです。
それでは具体的に何を知らないのが問題なんでしょうか、以下3つのカテゴリーに分類しました。
- 言語非依存のセキュアコーディング
- Java言語特有のセキュアコーディング
- APIやプラットフォーム固有のセキュアコーディング
3つ全てについて触れるとブログでは収まりきらないので、今回は2番目のJava言語特有のセキュアコーディングについてお話します。
突然ですが皆さん、次のコードの問題について指摘できますか?
ヒント:ボクシングとアンボクシングに注意することなんですが…
簡単すぎましたか?
答えはremoveメソッドに「i – 1」を引数として持たせていますが、これってint型になってますよね。
つまり、removeしたいが演算の結果がint型のためremoveできておりません。(このままでは値の削除ができていない!)
なのでshortでキャストしてあげなくてはなりません。
んぅ~デブサミの会場では腑に落ちなかった私…自宅に帰って調べるとEffective Javaにちゃんと載っているではありませんか。
詳細をここで書くとセキュアコーディングもとい、ボクシングの話になってしまいますので詳しくはEffective Java(第2版 P214- 項目49 ボクシングされた基本データより基本データ型を選ぶ)を参照してください。
せっかくなのでAndroid特有といえる問題をもう1つ!
次のコード、どこが問題か分かりますか?
ヒント:上記コードはSDカードの容量を取ってきているのですが、getAvailableBlocks()とgetBlockSize()はint型を返してくれます。
ヒントでほぼ分かってしまいましたか?
そうです。正解はintの最大値を超えるSDカード(およそ2GB)を読み込むと、オーバーフローしてしまうことです。
これの修正方法もlong型にキャストして演算させてあげればよいでしょう。
如何でしたでしょうか?
私が思ったのは、もっとJavaを理解して、過去の過ちを繰り返さないように様々なコードに触れなければならないということです。
特に前述したSDカードの問題では、2GB以上のSDカードが使用されることを想定しなければなりません。
2GB以上のSDカードを挿入した状態でテスティングでもしないと、発見は難しそうですよね…
しかし、私と皆さんはここで学んだので同じ過ちを繰り返す心配がありません!(忘れなければ)
こうやって一つ一つ学んでセキュアコーディングを目指しましょう。
ではでは。