外部入力に基づく権限チェック

外部入力に基づく権限チェック

説明

外部入力から作った権限文字列を Subject.isPermitted、checkPermission、checkCallingOrSelfPermission などへ渡すと、攻撃者がチェック対象を変えられる場合があります。保護する操作に必要な権限ではなく、攻撃者が選んだ権限を確認してしまい、認可が機能しなくなるおそれがあります。

想定される影響

  • 機密性の高い機能へのアクセス制御の回避
  • 内部APIやコンポーネントの悪用
  • 誤った権限判断によるデータ漏えい

対処方法

  1. 権限名は定数または許可リストから選んでください。
  2. Intentのextra、リクエストパラメーター、IPCの入力を権限文字列として直接使わないでください。
  3. 必要に応じて、呼び出し元のUID、パッケージ、署名の検証も併用してください。

例

変更前

java
String action = request.getParameter("action");
if (subject.isPermitted("account:read:" + action)) {
    doIt();
}

変更後

java
String action = request.getParameter("action");
if (Set.of("profile", "settings").contains(action)
        && subject.isPermitted("account:read:" + action)) {
    doIt();
}

解説:

  • 変更前: リクエストの action を検証せずに権限文字列へ追加すると、チェックする権限名を攻撃者が選べます。
  • 変更後: 動的な末尾部分が必要なら、サーバー側の許可リストを通った値だけを使ってください。固定機能は定数の権限文字列でチェックします。省略された doIt() の実際の操作と対象も、チェックした権限に対応する必要があります。

参考資料