More Related Content
Similar to Java/Androidセキュアコーディング (20)
Java/Androidセキュアコーディング
- 2. 自己紹介
§ 久保 正樹(くぼ まさき)
masaki.kubo@jpcert.or.jp
§ 脆弱性アナリスト@JPCERTコーディネーションセンター
§ GSSP-Cプログラマ、ISO/IEC SC27 WG4 エキスパート
§ プログラミングとの出会いはコンピュータ音楽から。前職は
ソニー(株)でVAIOのソフトウェア開発。退職後、ダートマス
大学で電子音響音楽修士。2005年からJPCERTコーディ
ネーションセンターで情報セキュリティに従事。
Developers Summit 2012
- 3. 自己紹介
§ 先月、本を出しました!
『Javaセキュアコーディング CERT/Oracle版』
http://www.amazon.co.jp/dp/4048860704
歌代 和正(監修)
久保 正樹, 戸田 洋三(翻訳)
アスキー・メディアワークス(2012/1/27)
Developers Summit 2012
- 8. モバイルアプリのトップ10リスク(OWASP)
§ M1 危険なデータ保存
§ M2 不十分なサーバー側のコントロール
§ M3 トランスポート層の保護が不十分
§ M4 クライアントサイドインジェクション
§ M5 お粗末な認証・認可の実装
§ M6 セッション管理不備
§ M7 信頼できない入力に基いたセキュリティ上の判断
§ M8 サイドチャンネルでの情報漏えい
§ M9 暗号化メカニズムの欠陥
§ M10 センシティブな情報の漏えい
Developers Summit 2012
- 10. モバイルアプリの脆弱性
§ Tencent QQPhotoのパスワードハッシュ漏
えい
§ Kaixin001のコンタクトと平文パスワードを読
まれる問題
§ 360 MobileSafeのSMSメッセージを読まれ
る問題
§ …
基本的な間違いが繰返されている…
JVN iPedia を "Android"をキーワードに検索
Developers Summit 2012
- 12. 新しいプラットフォームで繰り返される
過去の過ち
§ Androidという新しいプラットフォーム
§ アプリ250億ダウンロード(2011)
§ 大きなマーケットシェア+金銭的価値=攻撃
§ 繰り返される、過去の過ち
§ 暗号化鍵のハードコーディング: 42%
§ 乱数のエントロピー不足:61%
§ センシティブな情報の外部送信:39%
§ エラーメッセージにセンシティブな情報:6%
Veracode, State of Software Security Report. 2011
Developers Summit 2012
- 13. なぜ同じ過ちが繰り返されるのか?
§ プログラマが「知らない」
§ 古い脆弱性が新しい脆弱性
§ プラットフォームが成熟過程
§ 新たな脅威・攻撃手法が日々発見される世の
中
§ 経験年数がものを言わない
§ サプライチェーン
§ 知っている(分かっている)けどできない!
数年前のウェブアプリ脆弱性のデジャヴ
Developers Summit 2012
- 14. 何を知らないのが問題?
言語非依存のセキュアコーディング
1.
入力値検査、FileI/O
Java言語特有のセキュアコーディング
2.
OOP, Javaの型システム, expressionsなど
言語仕様、標準APIに関するコーディングテクニック
3.
APIやプラットフォーム固有の
セキュアコーディング
J2EE/Android SDK,プラットフォームのセキュリティモデル
Developers Summit 2012
- 15. セキュアコーディング
§ プログラムのある種の欠陥が脆弱性を生む
§ 仕様/デザインの欠陥
§ コーディングエラー
§ パターンがある
§ セキュアコーディングとは
§ プログラマが脆弱性を作り込まないコーディング
を実践する
§ 言語、API、プラットフォームを安全に(安全なところだ
け)使いこなす
Developers Summit 2012
- 18. Apache StrutsのXSS(2)
import java.io.Serializable;!
問題のあるコード
import java.util.Locale;!
!
import org.apache.commons.lang.StringUtils;!
!
// The Default ActionProxy implementation!
… !
Protected DefaultActionProxy(…, String actionName, String
methodName, …) {!
LOG.debug("Creating an DefaultActionProxy for namespace "!
+ namespace + " and action name " + actionName);!
" "!
!
"this.actionName = actionName;!
"this.namespace = namespace;!
"this.executeResult = executeResult;!
"this.method = methodName;! ActionNameとmethodNameは
}! 外部から受け取ったデータ
https://issues.apache.org/jira/secure/attachment/12472293/WW-35791-4.patch
Developers Summit 2012
- 19. Apache StrutsのXSS(3)
エラー画面の出力でXSS
攻撃者
webサーバ
細工された入力
http://...home.action?...action!login<script>alert(document.cookie)</
script>:cantLogin=some_value
struts
actionName = login<script>alert(document.cookie)</script>
action1 methodName = cantLogin=some_value
action2
action3
Developers Summit 2012
- 20. Apache StrutsのXSS(4)
修正後
import org.apache.commons.lang.StringEscapeUtils;!
import org.apache.commons.lang.StringUtils;! Apache Commons ライブラリの
import java.io.Serializable;!
escape*()を活用して無害化
import java.util.Locale;!
!
// The Default ActionProxy implementation!
…!
Protected DefaultActionProxy(…, String actionName, String methodName, …) !
{!
LOG.debug("Creating an DefaultActionProxy for namespace "!
+ namespace + " and action name " + actionName);!
!
!
this.actionName = StringEscapeUtils.escapeHtml(actionName);!
this.namespace = namespace;!
this.executeResult = executeResult;!
this.method =
StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml(methodName));!
}!
https://issues.apache.org/jira/secure/attachment/12472293/WW-35791-4.patch
Developers Summit 2012
- 21. 言語非依存のセキュアコーディングルール
§ 入力値検査
§ パス名は正規化してから検証する
§ ユーザ入力は無害化してからログに保存
§ ファイル名やファイルパスにはASCII文字
セットのみを使用する
§ File I/O、NW I/Oの両端で互換性のある文
字エンコーディングを使う
Developers Summit 2012
- 23. サブクラスの依存性を保つ(1)
extends
java.util.Hashtable!
java.util.Properties! extends
put()!
java.security.Provider!
remove()!
put()!
entrySet()!
remove()!
JDK1.2で追加された
entrySet()!
(スーパークラスに対する変更)
entrySet()
Developers Summit 2012
- 27. 条件演算子 ? : (1)
Q. System.out.println()は何を出力する?
char alpha = ‘A’;!
int i = 0;!
System.out.println(true ? alpha : 0);! A
System.out.println(true ? alpha : 65536);! 65
System.out.println(true ? alpha : i);
65
Developers Summit 2012
- 28. 条件演算子 ? : (2)
char alpha = ‘A’;!
int i = 0;!
System.out.println(true ? alpha : 0);!
System.out.println(true ? alpha : 65536);!
System.out.println(true ? alpha : i);
§ 型の評価はけっこう複雑
§ alphaの型はchar型(符号無し16ビット)
§ 問題は3番目の式の型
§ 0: char型で表現可能な定数式→char
§ 65536: charの最大値より1だけ大きい→二項格上げの
結果intに
§ i: 二項格上げの結果intに
Developers Summit 2012
- 29. Java/Androidでも整数オーバーフロー(1)
mezzofanti/AssetsManager.java:!
問題のあるコード
//@return the free space on sdcard in bytes!
public static long GetFreeSpaceB() {!
try {!
String storageDirectory =!
Environment.getExternalStorageDirectory().toString();!
StatFs stat = new StatFs(storageDirectory);!
return stat.getAvailableBlocks() * stat.getBlockSize();!
}!
catch (Exception ex) {!
return -1;!
}!
}
Developers Summit 2012
- 33. Androidアプリの脆弱性事例(1)
問題
不適切なファイルパーミッション
脅威
ユーザがキー入力したプライバシー情報等、センシティブな情報を攻撃者に盗ま
れる
原因
• ユーザのキー入力は sqlite データベースファイル X と Y に平文で保存される。
これらのファイルのパーミッションが他のアプリから読取り可能に設定されてい
る。
• サードパーティ製ライブラリの中でデフォルトのパーミション
(OPEN_READWRITE) でSQLiteのデータベースファイルを作成しており、そ
れをそのまま使用しているのが原因。
#ls –al /data/data/com.XXX.android.XXXX
drwxr-xr-x 1 10119 10119 2048 Aug 29 12:20 .
drwxrwx--x 1 1000 1000 2048 Aug 29 12:19 ..
drwxrwx--x 1 10119 10119 2048 Aug 29 12:20 cache
drwxrwx--x 1 10119 10119 2048 Aug 29 12:20 databases
drwxrwx--x 1 10119 10119 2048 Aug 29 12:20 files
drwxr-xr-x 1 1000 1000 2048 Aug 29 12:19 lib
-rw-r--r-- 1 10119 10119 5120 Aug 29 12:20 X
-rw-r--r-- 1 10119 10119 5120 Aug 29 12:20 Y
Developers Summit 2012
- 34. Androidアプリの脆弱性事例(1)
§ SQLiteDatabase.openOrCreateDatabaseで指定
できるパーミションはすべてworld redable!
§ サードパーティ製ライブラリはこちらを使っていた
§ android.database.sqlite.SQLiteOpenHelper
クラスのgetWritableDatabaseを呼び出すと、
§ android.content.Context.openOrCreateDatabaseを呼んでく
れる!
§ パーミッションを細かく設定できる(mode_privateとか)!
Developers Summit 2012
- 35. Androidアプリの脆弱性事例(2)
問題
ContentProviderの実装不備によるディレクトリトラバーサル
原因
Uriクラスは基本的に入力値検査しない。そのため、無効な入力が行われても、
例外をスローせず、ゴミデータを返す。
脅威
Uriオブジェクトは,URIを「/」でsegmentに分割し、各segmentをURLデコードす
る。攻撃者はURIにURLエンコードした文字列を含めることで、デコードされた結
果生成される文字列をコントロールできる。
public ParceFileDescriptor openFile(Uri uri, String mode) {!
File file = new File("/mnt/sdcard/XXX/", uri.getLastPathSegment()):!
!
return ParceFileDescriptor.open(file, ParceFileDescriptor.MODE_READ_ONLY);!
}
public abstract String getLastPathSegment()!
Returns
the decoded last segment or null if the path is empty
Developers Summit 2012
- 36. Androidアプリの脆弱性事例(3)
// getPathSegments()メソッドの実装から抜粋!
! pathを取得
2090 String path = getEncoded();!
2091 if (path == null) {!
2092 return pathSegments = PathSegments.EMPTY;!
2093 }!
2094!
2095 PathSegmentsBuilder segmentBuilder = new
PathSegmentsBuilder();!
2096! pathから先頭の/を探す
2097 int previous = 0;!
2098 int current;!
2099 while ((current = path.indexOf('/', previous)) > -1) {!
2100 // This check keeps us from adding a segment if the path
starts!
2101 // '/' and an empty segment for "//".!
2102 if (previous < current) {! pathを分割してデコード
2103 String decodedSegment!
2104 = decode(path.substring(previous, current));!
2105 segmentBuilder.add(decodedSegment);!
2106 }!
2107 previous = current + 1;!
2108 }!
プラットフォーム側の問題とも言える…
Developers Summit 2012
- 41. [宣伝1]
Androidセキュアコーディングセミナー
§ 日時:3月14日 13:00〜19:00 @ 翔泳社
§ タイトル『Androidセキュアコーディングセミナー〜
安全なアプリ開発のための基礎知識』
§ Androidセキュリティー概論から実機を使ったセキュリ
ティコードレビューまで
§ 脆弱性を作り込まないテクニック教えます!
§ 初回限定35,000円(税込36,750円)
§ お申込みは、CodeZineのHPで!
http://codezine.jp/seminar/
Developers Summit 2012
- 42. [宣伝2]
出張セミナーやってます
§ C/C++, Javaのセキュアコーディング
§ [実績] 大手家電メーカー、ゲームメーカー
§ [時間、内容] ご相談に柔軟に応じます!
§ 全国どこへでも
§ お問い合わせ、ご用命は
§ セキュアコーディング担当:佐藤まで
§ secure-coding@jpcert.or.jp
Developers Summit 2012