コラム

「セキュアコーディングガイド 最新版」JSSEC技術部会 セキュアコーディング WG 副リーダー 福本 郁哉(株式会社SRA)

日本スマートフォンセキュリティ協会(JSSEC)は 2017年2月 、都内のベルサール神田において、「JSSEC セキュリティフォーラム 2017 スマートフォン/IoT、その先にある ICT社会のセキュリティについて考える」を開催しました。JSSEC では、これまで「スマートフォンのセキュリティ」をテーマに様々な活動を展開しています。今回は「IoT」や「AI」「制御システム」など、スマートフォンから一歩踏み込んだ講演を企画する一方、以前から人気の技術部会セッションも顕在。JSSEC セキュアコーディング WG 副リーダー 福本 郁哉氏(株式会社SRA)の講演では、最新版となる「Androidアプリのセキュア設計・セキュアコーディングガイド 第8版」について紹介しました。

アプリケーションでたびたび見つかる脆弱性。サイバー攻撃者にとって、脆弱性は恰好の攻撃対象です。アプリケーション開発の際には、いかに脆弱性を作り込まないようにするかが大切。そこで注目されているのが、脆弱性を作り込まないプログラミングの技法である「セキュアコーディング」です。

スマートフォンの専門家が集う日本スマートフォンセキュリティ協会(JSSEC)では、安全なアプリ開発を支援するため、「Androidアプリのセキュア設計・セキュアコーディングガイド(以下、セキュアコーディングガイド)」を独自に作製し、公開しています。

2012年6月に初版を公開。以降もAndroidのバージョンアップをキャッチアップしつつ、積極的に改訂を進めており、直近1年だけでも第7版(2016年9月)、第8版(2017年2月)と、2度の改訂を行ないました。

福本氏は「セキュアコーディングガイドは開発の利用シーンに沿った形で構成しており、設計や実装において安全なアプリを作るという視点で作られています」と講演冒頭でガイドのコンセプトを紹介しつつ、第7版のトピックスと最新となる第8版のポイントについて解説しました。

第7版のトピックスは「Pinning検証」と「HTTPリクエストヘッダ」設定時の注意点

2016年8月にリリースした第7版は、Androidアプリにおいて「Pinning検証」を実装する際の注意ポイント、「HTTPリクエストヘッダ」設定時の注意点などを取り上げています。

Androidアプリでは、 https通信の検証処理の1つとして、通信先のサーバから証明書チェーンが届くと「ルート認証局(CA)までたどれるかどうか」を検証しています。証明書のチェーンとは、使用する証明書の集合体で、通常ソフトウェア開発キット(SDK)のライブラリが内部で行うため、特別な処理を挟むといったことがない限り、開発者自身が検証ツールを実装することはありません。

とはいえ、第三者による「CAから秘密鍵の盗難」、「CAへのなりすまし」、「不正な証明書の発行」など、その前提が崩れることも否定できず、「証明書チェーンのなかに偽の証明書が含まれる」リスクについて福本氏は説明しました。

さらに「アプリと通信先のサーバとの間に攻撃者が割り込んで中間者攻撃が行われると、攻撃者がアプリに対して証明書のチェーンを送り返すことができるようになる」と指摘します。

攻撃者が正規の証明書チェーンのなかに悪意ある証明書を追加してもSDKのライブラリでは区別がつかず、クライアント側では「正しいもの」として認識してしまうおそれがあります。

この問題を解決するために使われるのが「Pinning検証」です。これはアプリが本来通信するはずのサーバ証明書、もしくはその公開鍵を事前にアプリのなかに保持しておく手法です。本当に通信したい相手の証明書の情報が含まれているか検証し、含まれていなければ通信を遮断します。

しかしながら、福本氏によれば「『Pinning検証』にも落とし穴がある」といいます。JavaのAPIを用いて取得される証明書チェーンでは「Pinning検証」ができません。

「これはAPIの仕様であって、バグではありません。しかし仕様がわかりにくいために、間違った実装がなされてしまう」と福本氏は問題点を指摘。「セキュアコーディングガイド第7版では、『Pinning検証』を行う際に、使っていけないAPIとして取り上げています」(福本氏)。

一方HTTPリクエストヘッダ設定時の注意点については、以前から「URLConnectionクラス」に「httpヘッダインジェクション」の脆弱性があると指摘されていました。これは 「Androidバージョン2.2」から「同6.0」までのSDKで、脆弱なバージョンの「OkHttp」が使われていたことが原因です。

同問題への対応は比較的簡単で、 APIが引き受けなかった入力値チェックを、アプリで実装することで解決できます。セキュアコーディングガイドにも実装するためのサンプルコードを第7版で収録しました。

「Android 7.0」に対応した第8版ではバグや脆弱性の回避が容易に

続いて福本氏は、今回お披露目となった第8版の紹介に移りました。第8版からは「Android 7.0 Nougat(ヌガー)」に対応したことが大きなポイントであるとし、福本氏は、第8版のトピックスとして、「Network Security Configuration」と「外部ストレージへのアクセスに関する仕様変更」を取り上げました。

「Network Security Configuration」は、「Android 7.0」のセキュリティ強化における目玉とも言えるもので、アプリのネットワーク通信に関するセキュリティの設定を、 XMLの記述だけで行えるものです。例えば、「プライベート証明書の使用」「Pinning検証」「アプリの非暗号化通信抑制」「デバッグ時だけ有効になるCAの設定」などが設定できます。

福本氏は、「従来、これら機能をアプリに実装する場合、多かれ少なかれ、開発者が自分でコーディングする必要がありましたが、すべてXMLで簡単に設定できるようになりました」と解説。「これによってバグとか脆弱性の作り込みを阻止することが可能になります」とメリットを強調しました。

プライベート証明書の使用については、XMLに通信先ドメインを記述するだけで済むようになります。 通信先ドメインを指定することはもちろん、「base-config」と指定するだけで、アプリが行うすべてのhttps通信に対してプライベート証明書を使用するよう指定することも可能です。

「Pinning検証」についても、通信先サーバを指定した上でピン止めしておきたい公開カギのハッシュ値を記述すれば、アプリで自動的に検証します。「Android 6.x」の時点では、「Pinning検証」で使用するAPIの選択について注意が求められることは先に説明したとおりですが、まさに「Android 7.0」の「Network Security Configuration」によって同問題に対する解決策が提供されています。

またアプリの非暗号化通信を抑制することもできます。以前からiOSで導入されていた、暗号化通信を強制するATSという機能に類似した機能といえます。非暗号化通信を許可しないよう記載しておくだけで、http通信やftp通信において暗号化されていない通信を阻止することができるようになります。

ただし、見落としがちな点もあります。福本氏は、「この設定は『WebView』には適用されない仕様ですので、その点は注意していただきたい」と述べました。

開発者にとってメリットが多い「Network Security Configuration」ですが、さらに福本氏は「個人的に一番インパクトが大きかった機能」としてデバッグ専用CA証明書を挙げました。デバッグ時だけプライベート証明書を使うという設定を簡単に組み込むことが可能になります。

これまでもSSL/TLSサーバ証明書を正しく検証しておらず、盗聴などのおそれがある脆弱性が多数のアプリで指摘を受けています。

「開発者にヒアリングしてみると、その多くは検証目的の開発コードが、リリース版に紛れてしまったとの答えでした(福本氏)」。多くの開発者が困っていた部分ですが、今回の仕様変更でデバッグ専用サーバ証明書を明示的に設定できるようになったため、テスト環境向けに危険な実装を行う必要がなくなるというのは、大きな利点です。

「Android 7.0」では外部ストレージの扱いが大きく変更
「Android 7.0」からは、外部ストレージへのアクセスに関する仕様変更も変更されます。まず「MODE_WORLD_READABLE」「MODE_WORLD_WRITEABLE」が、ついに「Android 7.0」から使用できなくなります。どのようなアプリからでも、外部ストレージへのアクセスが許可でき、リスクが高いと指摘されていました。「Android 4.2」から非推奨となっていたものの、使用できる状態になっていたのです。

ふたつ目は「Scoped Directory Access」という機能です。これは外部ストレージの特定の公開ディレクトリ対して、パーミッションなしでアクセスする方法をシステムとして提供するものです。

例えば写真アプリで利用する「Pictures」という公開ディレクトリにアクセスしたいニーズは多いのですが、従来の手段でアクセスを許可すると、「Pictures」以外の公開ディレクトリへもアクセス権を与えてしまったり、ユーザビリティに支障が出るなど、使い勝手が良くありませんでした。

しかし、今回導入された「Scoped Directory Access」を用いれば、指定した特定ディレクトリに対してのみ、パーミッションなしでアクセスできるようになりました。ユーザーは初回アクセス時に許可を認めるダイアログに回答するだけとなります。

福本氏は「パーミッションを付与して、不必要なディレクトリにもアクセスをさせるよりも、『Scoped Directory Access』の仕組みを利用して、必要なディレクトリだけアクセスさせる方法をセキュアコーディングガイドでは推奨しています」と紹介しました。

その他、第8版では、「Android 2.x」「同3.x」などの古いバージョンをターゲットにしたアプリ開発に関する記述の整理、「intent-filter定義」の有無とコンポーネントの公開設定についての解説、「Sticky Broadcast」についての追記など改訂を行っています。福本氏は最後に第8版の細かな改定ポイントについても触れ、講演を終えました。

【編集協力:Security NEXT 企画制作部】