SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Javaセキュアコーディング入門

ContentProviderのアクセス範囲
――Dropboxにおける脆弱性の修正

Javaセキュアコーディング入門(2)

  • このエントリーをはてなブックマークに追加

 本連載では、セキュアコーディングスタンダード「CERT Oracle Secure Coding Standard for Java」の内容をベースに、Android特有の情報を交えつつ、堅牢なプログラムを開発するためのノウハウを具体的な事例とともに紹介していきます。第2回では、さっそくAndroidの話題をとりあげます。AndroidのContentProviderを使うときの注意点を解説します。

  • このエントリーをはてなブックマークに追加

はじめに

 Androidにはデータを読み書き/共有するための仕組みとしてContentProviderがあります。データの読み書きを簡単に実装するためのインターフェースも備えていて便利なものです。また、Androidでは基本的に他のアプリケーションとデータをやり取りすることはできません。自分が作成したアプリケーションのデータを他のアプリケーションで利用してもらう場合、データを共有する方法の一つとして、ContentProviderを活用できます。例えば、Android端末に標準でインストールされているContacts(連絡先)のデータはContentProviderを使用して取得することができます。

 アプリケーション内でのデータの読み書きを簡単に実装することができたり、他のアプリケーションとデータを共有することができたりと便利な仕組みですが、そのアクセス範囲を意識しておかないと、本来は公開したくない情報まで外部に公開してしまい、他のアプリケーションから自由にアクセスされてしまいます。

アクセス制限方法

 では実際にアクセスを制限する方法を見ていきましょう。独自のContentProviderを実装していく上でマニフェストファイル(AndroidManifest.xml)に登録を行いますが、その部分でパーミッションを設定し、ContentProviderを非公開にするか他のアプリケーションにも公開するのかアクセスできる権限を指定することになります。

他のアプリケーションに公開

 例えば、ContentProviderを継承してSampleContentProviderを実装したとし、マニフェストファイルに次のように記述したとします。

<provider android:name="SampleContentProvider"
          android:authorities="com.example.app.Provider" />

 パーミッションを指定していないこのような場合は、他のアプリケーションからSampleContentProviderにアクセスすることができます。

非公開

 このContentProviderを持っているアプリケーションだけがアクセスできるように制限するには、android:exportedプロパティを明示的にfalseにします。こうすると、他のアプリケーションからは一切アクセスできなくなります。

<provider android:name="SampleContentProvider"
          android:authorities="com.example.app.Provider"
          android:exported="false" />

特定のパーミッションで制限

 指定されたパーミッションを宣言しているアプリケーションのみアクセスできるようにするには、android:permissionプロパティにパーミッション名を記述し、permission要素で宣言します。

<provider android:name="SampleContentProvider"
          android:authorities="com.example.app.Provider"
          android:permission="com.example.app.permission.Provider" />

<permission android:name="com.example.app.permission.Provider" />

 こうすることで、uses-permission要素でそのパーミッションを要求しないと、アプリケーションではSampleContentProviderにはアクセスできなくなります。

<uses-permission android:name="com.example.app.permission.Provider" />

同じ署名を持ったアプリケーションのみ

 同じ署名を持ったアプリケーションのみSampleContentProviderにアクセスできるようにするには、permission要素のandroid:protectionLevelプロパティにsignatureと記述します。

<provider android:name="SampleContentProvider"
          android:authorities="com.example.app.Provider"
          android:permission="com.example.app.permission.Provider" />

<permission android:protectionLevel="signature"
            android:name="com.example.app.permission.Provider">
</permission>

 こうすることで、SampleContentProviderにアクセスできるアプリケーションを、特定のパーミッションを許可されていることに加えて、元のアプリケーションと同じ署名を持っているもののみに制限することができます。

実際にあった例

 DropboxのAndroid用クライアントアプリケーションであるDropbox for AndroidでこのContentProvider絡みの脆弱性が実際にありました。

 この脆弱性があったバージョンのうち、1.1.3のマニフェストファイルを確認すると、ContentProviderを継承したDropboxProviderに対して、

<provider android:name=".provider.DropboxProvider"
          android:authorities="com.dropbox.android.Dropbox">
    <grant-uri-permission android:pathPrefix="/" />
</provider>

 このように特にアクセス制限をかけていなかったため、他のアプリケーションからも読み書きなどが自由にできる状態になっており、例えば、他のアプリケーションからデータベースに変更を加え、Dropboxの公開用フォルダである「Public」フォルダにDropboxのアカウント情報が含まれている設定ファイルをアップロードさせたりすることが可能でした。

 現在の最新バージョン(執筆時点で1.2.4)では、この問題に対して以下のように対策されています。

<provider android:name=".provider.DropboxProvider"
          android:exported="false"
          android:authorities="com.dropbox.android.Dropbox">
    <grant-uri-permission android:pathPrefix="/" />
</provider>

 このようにandroid:exportedプロパティでfalseを指定し、他のアプリケーションからはアクセスできないようになっています。

まとめ

 ContentProviderはデータの読み書き/共有を実装する上で便利なものですが、そのデータは本当に他のアプリケーションに公開する必要があるのか、また、公開する場合もContentProviderにアクセスできる範囲をしっかり意識して設定する必要があります。

参考文献

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
Javaセキュアコーディング入門連載記事一覧

もっと読む

この記事の著者

熊谷 裕志(JPCERTコーディネーションセンター)(クマガイ ヒロシ(JPCERTコーディネーションセンター))

情報セキュリティアナリスト JPCERTコーディネーションセンターベンチャ企業にてWEBサイトのデザインやシステム開発、Androidアプリケーションの開発などに従事したのち、2011年4月よりJPCERTコーディネーションセンターにて、脆弱性情報の分析やセキュアコーディングの普及活動に携わってい...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/6286 2011/11/29 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング