Hello there, ('ω')ノ
📬 インテントとは?
インテント(Intent)とは、Androidアプリ間やアプリ内部で処理を依頼するための通信メッセージです。 たとえば:
- 他のアプリを起動(例:写真をカメラで撮る → LINEで送る)
- アクティビティ(画面)を切り替える
- サービスを起動する
- ブロードキャストで通知を送る(例:電源接続時の通知)
Intent intent = new Intent(); intent.setAction("com.example.ACTION_SEND_DATA"); intent.putExtra("token", "123456"); sendBroadcast(intent);
このように、名前付きのイベント+データを他アプリや内部モジュールへ渡すことができます。
❗ インテントの脆弱性とは?
インテントは便利な反面、「誰でも呼び出せる or データを受け取れる」構造にしてしまうと、外部から悪意あるリクエストを受けるリスクが発生します。
主な脆弱性パターン:
| 脆弱性名 | 説明 |
|---|---|
| インテントインジェクション | 外部アプリが内部アクティビティやサービスを勝手に呼び出す |
| 情報漏洩(Exported Activity) | 本来内部用の処理に外部アプリがアクセスできてしまう |
| 任意コード実行 | 渡されたデータをそのまま eval() 的に実行してしまう |
| 不正なデータの挿入 | 悪意あるintentでアプリがクラッシュ・誤動作 |
🧪 例:インテントインジェクションの危険性
<!-- AndroidManifest.xml --> <activity android:name=".AdminActivity" android:exported="true" />
この状態で AdminActivity にログインチェックなどがなければ、他のアプリから簡単に起動できてしまいます。
adb shell am start -n com.target.app/.AdminActivity
→ 誰でもアドミン画面にアクセス可能=セキュリティ破綻
🔍 診断時のチェックポイント
✅ Manifestファイルのexported属性
activity/service/receiverにandroid:exported="true"が付いていないか?- もしくは
intent-filterがついているだけでexportedが指定されていない場合、Android 12以降はビルドエラーになりますが、旧バージョンでは勝手にexported扱いになることも。
✅ インテントの送信先/受信側の制御
startActivity()やsendBroadcast()で、**明示的な宛先指定(明示的インテント)**を使っているか?IntentFilterで複数アプリから受信できる設定にしていないか?- 受け取ったデータを検証せずに処理していないか?
✅ Drozerによる診断例(動的解析)
Drozerを使うと、以下のような確認ができます:
run app.activity.info -a com.target.app run app.activity.start --component com.target.app com.target.app.AdminActivity
→ 不正に起動できてしまった場合、そのアクティビティはexportedかつ認証なしで呼び出せるという重大なリスクを抱えています。
🛡️ 対策方法
| 対策 | 内容 |
|---|---|
android:exported="false" に設定 |
内部専用アクティビティ/サービスは外部に公開しない |
| 明示的インテントを使用 | setComponent() などで宛先を限定 |
| データの検証 | getIntent().getStringExtra() の内容を必ずチェック |
| 認証・認可の導入 | アプリ内部の重要な画面や処理にはログインチェックを設ける |
| セキュリティログの追加 | 不審なインテント呼び出しを記録する |
✅ まとめ
- インテントはAndroidアプリ間通信の重要な機能だが、exportedの扱いを誤ると外部から不正に呼び出される
- Manifestの
exported属性とintent-filterの組み合わせに注意 - Drozerなどで不正アクセス可能かを実機検証することが重要
- アプリの内部機能は「外部に見せない」「必ず検証する」という原則を守ろう!
Best regards, (^^ゞ