開発者の不注意や確認不足が、脆弱性につながることが理解できたと思います。
次は、サンプルコードを基に対策方法を学んでいきましょう。
対策方法の概要
実際に脆弱性のあるソースコードを確認し、修正してみましょう。
まず、「ソースコードを開く」ボタンをクリックし、「AndroidManifest.xml」を開いてください。
ソースコードを開く
修正前:
プロジェクト |
ComponentService |
ソースファイル |
AndroidManifest.xml |
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.go.ipa.sample.component.service"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
<!-- ▼▼▼脆弱性のあるソースコード▼▼▼ -->
<!-- exported属性をtrueに設定。 -->
<service
android:name=".BackupService"
android:exported="true" >
</service>
<!-- ▲▲▲脆弱性のあるソースコード▲▲▲ -->
|
このアプリには脆弱性対策を行うべき箇所が3箇所あります。修正例は以下の通りです。
-
Permission使用の宣言を追加する
修正前ソースコードの10行目と11行目の間にアプリで使用するPermissionの宣言を追加します。
ServiceをPermissionで保護するためには、保護に使用するPermissionを使うことを宣言する必要があります。
修正後ソースコードの11~13行にあたります。
<uses-permission android:name="jp.go.ipa.sample.component.service.permission.LAUNCH_SERVICE"/>
-
独自のPermissionの定義を追加する
上の修正に続けて、Serviceの保護に使用する独自のPermissionの定義を追加します。
android:protectionLevelで設定するPermissionの保護レベルにsignatureを設定することにより、Permissionを定義した側のアプリと同じ署名を持ったアプリにのみPermissionの使用を許可します。
修正後ソースコード16~18行目にあたります。
<permission
android:name="jp.go.ipa.sample.component.service.permission.LAUNCH_SERVICE"
android:protectionLevel="signature"/>
-
ServiceをPermissionで保護する
修正前ソースコードの31行目に、上で定義したServiceの保護に使用するPermissionの指定を追加します。
これにより、このServiceには指定したPermissionを持つアプリしかアクセスできなくなります。
修正前ソースコードの31行目末尾の「>」を削除し、31行目と32行目の間に以下のコード(赤文字部分)を追加してください。
修正後ソースコード42行目にあたります。
<service
android:name=".BackupService"
android:exported="true"
android:permission="jp.go.ipa.sample.component.service.permission.LAUNCH_SERVICE">
</service>
Permissionで保護するServiceのandroid:exported属性の設定も確認しておきましょう。
android:exported属性が指定されていない、または、android:exported属性にfalseが設定されていた場合は、Serviceが非公開となり、指定したPermissionを持ったアプリからもアクセスできなくなってしまうためです。
修正後:
プロジェクト |
ComponentService |
ソースファイル |
AndroidManifest.xml |
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.go.ipa.sample.component.service"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8" />
<!-- ▼▼▼脆弱性を修正したソースコード▼▼▼ -->
<uses-permission android:name="jp.go.ipa.sample.component.service.permission.LAUNCH_SERVICE"/>
<!-- ▲▲▲脆弱性を修正したソースコード▲▲▲ -->
<!-- ▼▼▼脆弱性を修正したソースコード▼▼▼ -->
<permission
android:name="jp.go.ipa.sample.component.service.permission.LAUNCH_SERVICE"
android:protectionLevel="signature"/>
<!-- ▲▲▲脆弱性を修正したソースコード▲▲▲ -->
<!-- ▼▼▼脆弱性を修正したソースコード▼▼▼ -->
<!-- exported属性をtrueに設定。 -->
<service
android:name=".BackupService"
android:exported="true"
android:permission="jp.go.ipa.sample.component.service.permission.LAUNCH_SERVICE">
</service>
<!-- ▲▲▲脆弱性を修正したソースコード▲▲▲ -->
|
最後に、Permissionで保護された「05データバックアップ」アプリのServiceを利用する「05データバックアップクライアント」アプリも同じPermissionを使用するよう修正しましょう。
「ソースコードを開く」ボタンをクリックし、「AndroidManifest.xml」を開いてください。
ソースコードを開く
修正前:
プロジェクト |
ComponentServiceClient |
ソースファイル |
AndroidManifest.xml |
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
|
使用するPermissionが宣言されていません。このままだと、Serviceを起動しようとした際にSecurityExceptionが発生してしまいます。「05データバックアップ」アプリのServiceに設定したPermissionをアプリで使用するよう宣言しましょう。
修正前ソースコードの10行目と11行目の間に、Permissionの使用を宣言します。
修正後ソースコードの11行目にあたります。
<uses-permission android:name="jp.go.ipa.sample.component.service.permission.LAUNCH_SERVICE"/>
修正後:
プロジェクト |
ComponentServiceClient |
ソースファイル |
AndroidManifest.xml |
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8" />
<uses-permission android:name="jp.go.ipa.sample.component.service.permission.LAUNCH_SERVICE"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
|
対策のまとめ
「公開コンポーネントのアクセス制限不備」による脆弱性について、対策は以下のとおりです。