セキュアコーディングガイド
最新版のご紹介JSSEC セキュアコーディングWG
福本 郁哉© 2017 JSSEC

1Agenda• セキュアコーディングガイドの歩み•〃
第7版 (2016年9月1日版) の改訂内容•〃
第8版 (2017年2月1日版) の改定内容© 2017 JSSEC

2

セキュアコーディング
ガイドの歩み© 2017 JSSEC

3

2012年6月 初版公開
Androidアプリセキュリティの教科書
Androidアプリセキュリティのノウハウ集
http://www.jssec.org/report/securecoding.html

通称 「JSSECセキュアコーディングガイド」
PDF文書とサンプルコード
無償・商用利用可
利用ケースに応じた内容• 「Activityを作る・利用する」• 「HTTPS通信する」• etc.
• 通信キャリア、アプリベンダーで活用• アプリ発注の際の受け入れ基準にするケースも••••© 2017 JSSEC

4

ガイドの歩み• 年1~2回のペースで改訂
2012年6月

2012年11月

2013年4月2014年7月• 2014年 英語版リリース
2014年4月© 2017 JSSEC

2015年6月

2014年7月

2016年2月

2016年2月

5第7版 (2016年9月1日版)© 2017 JSSEC

6第7版 (2016年9月1日版)
前版（Android 6.x対応）で盛り込めなかった
脆弱性関係の記事、セキュリティアップデート情報など• Pinning実装の注意点• HTTPリクエストヘッダ設定時の注意点• etc.

© 2017 JSSEC

7

Pinning実装時の注意点© 2017 JSSEC

8

証明書チェーンの検証

https://www.cigital.com/blog/ineffective-certificate-pinning-implementations/© 2017 JSSEC

9

不正なCA証明書を使った攻撃
クライアントでの検証は、不正なCA証明書①で終了。
正しい証明書チェーンとみなされる
不正なCA証明書の作成＆MITMに成功した攻撃者

攻撃者が付け足した証明書チェーン※ 不正なCA証明書を含む

本来の証明書チェーン※ 正規のCA証明書を含む
https://www.cigital.com/blog/ineffective-certificate-pinning-implementations/© 2017 JSSEC

10

Pinning検証••

通信先サーバの証明書（の公開鍵）情報をアプリ内に保持（ピン留め）しておく
検証済み証明書チェーンの中に、ピン留めした証明書が含まれているかどうか確認する

ピン留め

https://www.cigital.com/blog/ineffective-certificate-pinning-implementations/© 2017 JSSEC

11

Pinning検証の落とし穴••

javax.net.ssl.SSLSession.getPeerCertificates()
javax.net.ssl.SSLSession.getPeerCertificateChain()

ピン留め

https://www.cigital.com/blog/ineffective-certificate-pinning-implementations/© 2017 JSSEC

12

Pinning検証の落とし穴を回避する•

net.http.X509TrustManagerExtensions.checkServerTrusted()• Android 4.2 (API Lv. 17）以上

ピン留め

https://www.cigital.com/blog/ineffective-certificate-pinning-implementations/© 2017 JSSEC

13

HTTPリクエストヘッダ設定時の注意点© 2017 JSSEC

14

HTTPリクエストヘッダ設定時の注意点• URLConnection クラスにHTTPヘッダインジェクションの脆弱性（Android 2.2 ～ 6.0）
https://jvn.jp/vu/JVNVU99757346/index.html• OkHttp (< 2.5.0) に由来• setRequestProperty()/addRequestProperty() を使用する際は、外部から受け取った値を使用する前に改行コードを排除する© 2017 JSSEC

15

その他の改訂ポイント• Provider Installerの紹介• Google Play開発者サービスの Security Provider が利用できる• Security Providerに脆弱性が見つかったとき、メーカー対応
を待たずとも、Google Play Storeを通じて（比較的）迅速にアップデートされる• サンプルコードの修正＆削除• 動かないサンプルアプリがありました• “WebView Assets”• 申し訳ありませんでした m(-_-)m• ガイドの内容と無関係なサンプルアプリがありました• “WebView Javascript Enable”• 実験のために作ったアプリでした• 実は第3版（日本語版）からあった• 誠に申し訳ありませんでした m(_ _)m© 2017 JSSEC

16

第8版 (2017年2月1日版)© 2017 JSSEC

17

明日公開（冊子版は本日会場限定配布）

https://www.jssec.org/report/securecoding.html© 2017 JSSEC

18

第8版 (2017年2月1日版)• カバーデザイン刷新• ４年ぶり２回目• Android 7.x 対応• Network Security Configuration• 外部ストレージへのアクセスに関する仕様変更• Scoped Directory Access• MODE_WORLD_READABLE/WRITEABLE 使用不可

• etc.

© 2017 JSSEC

19

カバーデザイン刷新© 2017 JSSEC

20

カバーデザインが新しくなりました

初代

二代目

三代目
© 2017 JSSEC

21

表紙のデザインが変わりました© 2017 JSSEC

22

Android 7.x 対応
Network Security Configuration© 2017 JSSEC

23

Network Security Configuration• アプリのネットワーク通信に関するセキュリティ設定を XML で行うことができる• プライベート証明書の使用• Pinning検証• 非暗号化通信（HTTP）の抑制• デバッグ専用CA証明書の使用• 追加コーディングの必要なし• バグや脆弱性の作り込み防止に効果あり© 2017 JSSEC

24

Network Security Configuration
プライベート証明書の使用

通信先ドメイン

プライベート証明書のパス© 2017 JSSEC

25

Network Security Configuration
プライベート証明書の使用© 2017 JSSEC

26

Network Security Configuration
プライベート証明書の使用<domain-config>：特定ドメインへのHTTPS通信↓<base-config>：全てのHTTPS通信© 2017 JSSEC

27

Network Security Configuration
Pinning検証

通信先ドメイン通信先サーバの公開鍵ハッシュ© 2017 JSSEC

28

Network Security Configuration
非暗号化（HTTP)通信の抑制

非暗号化通信を許可しない

 抑制対象は HTTP, FTP, DownloadManager, MediaPlayer 等

 低レイヤーの、トラフィックの内容が暗号化されているかどうか判別が難しい通信では「best effort」で実施される

 WebView には適用されない© 2017 JSSEC

29

Network Security Configuration
デバッグ専用CA証明書

 android:debuggable が true のとき（デバッグビルドのとき）
のみ、プライベートCA証明書を使用する
 非リリースビルドは Play Store に載らない
 デバッグ目的のためにサーバ証明書検証をバイパスさせてしまう、
危険な実装をしなくても済む© 2017 JSSEC

30

Android 7.x 対応
外部ストレージへのアクセスに関する仕様変更© 2017 JSSEC

31

MODE_WORLD_READABLE/WRITEABLE• MODE_WORLD_READABLE /MODE_WORLD_WRITEABLE• Android 4.2 (API Lv. 17) ～ 非推奨• Android 7.0 (API Lv. 24) ～ 使用不可
• セキュリティ例外がスローされる

SDNA「Androidアプリ脆弱性調査レポート 2015」© 2017 JSSEC

32

Scoped Directory Access• 外部ストレージの特定ディレクトリに対し、Permissionなしにアクセスできる
DIRECTORY_MUSIC

音楽ファイルDIRECTORY_PODCASTS

ポッドキャスト

DIRECTORY_RINGTONES

着信音

DIRECTORY_ALARMS

アラーム音

DIRECTORY_NOTIFICATIONS

通知音

DIRECTORY_PICTURES

画像ファイルDIRECTORY_MOVIES

動画ファイルDIRECTORY_DOWNLOADS

ユーザーがダウンロードしたファイル

DIRECTORY_DCIM

カメラによる画像・動画ファイル

DIRECTORY_DOCUMENTS

ユーザーによって作られたドキュメント© 2017 JSSEC

33

外部ストレージへのアクセス問題
Android 7.0 未満では……
外部ストレージの特定ディレクトリ（e.g. “Pictures”）に写真アプリなどがアクセスする際、以下のような問題があった• READ/WRITE_EXTERNAL_STORAGE→ 外部ストレージの全ての公開ディレクトリにアクセスできてしまう• Storage Access Framework→ 常に同じディレクトリにアクセスするアプリであっても、システムUIでユーザーにディレクトリを選択させる必要がある© 2017 JSSEC

34

Scoped Directory Access
StorageManager sm =(StorageManager)getSystemService(Context.STORAGE_SERVICE);
StorageVolume volume = sm.getPrimaryStorageVolume();Intent intent = volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
startActivityForResult(intent, request_code);
DIRECTORY_MUSIC

音楽ファイルDIRECTORY_PODCASTS

ポッドキャスト

DIRECTORY_RINGTONES

着信音

DIRECTORY_ALARMS

アラーム音

DIRECTORY_NOTIFICATIONS

通知音

DIRECTORY_PICTURES

画像ファイルDIRECTORY_MOVIES

動画ファイルDIRECTORY_DOWNLOADS

ユーザーがダウンロードしたファイル

DIRECTORY_DCIM

カメラによる画像・動画ファイル

DIRECTORY_DOCUMENTS

ユーザーによって作られたドキュメント© 2017 JSSEC

35

その他の改訂ポイント• Android 2.x, 3.x についての記述を整理• intent-filter定義の有無とコンポーネントの公開設定について解説• Activity, Receiver, Serviceについて、exported無指定の場合、デフォルトの挙動は…
<intent-filter> あり → 公開扱い
<intent-filter> なし → 非公開扱い• ガイドでは「intent-filterの有無によらず、exportedは明示的に指定すべし」としている• Sticky Broadcastについて追記• 不特定多数のアプリからアクセスできてしまう• なので、センシティブな情報は送信しないように• Android 5.0 (API Lv. 15)で非推奨© 2017 JSSEC

36

おねがい

© 2017 JSSEC

37

執筆へのご協力をお願いします
ご協力いただける方は下記の要領でご連絡ください
1.

JSSEC会員でない方はAndroidセキュリティ部へご参加ください

2.

– JSSEC技術部会副部会長 奥山謙– 会員かどうかは下記URLで確認•

下記までご連絡下さい
Ken.Okuyama@sony.com

http://www.jssec.org/members/– Androidセキュリティ部への参加は下記
URLからできます•

https://groups.google.com/group/android-security-japan

ご協力お願い致します© 2017 JSSEC38