Permission checks based on external input

Permission checks based on external input

Description

Passing a permission string built from external input to APIs such as Subject.isPermitted, checkPermission, or checkCallingOrSelfPermission can let an attacker change which permission is checked. Checking an attacker-selected permission instead of the one required for the protected operation may undermine authorization.

Potential impact

  • Bypass of access controls on sensitive operations.
  • Misuse of internal APIs or components.
  • Data disclosure caused by incorrect permission decisions.

Remediation

  1. Select permission names from constants or an allow-list.
  2. Do not use Intent extras, request parameters, or IPC input directly as permission strings.
  3. Combine permission checks with caller UID, package, or signature validation where required.

Examples

Before

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

After

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

Explanation:

  • Before: Appending the unvalidated action request parameter to a permission string lets the requester choose the permission to check.
  • After: If a dynamic suffix is necessary, accept only values on the server's allow-list. Check a fixed operation against a constant permission string. The actual operation and target in the omitted doIt() body must also correspond to the checked permission.

References