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
- Select permission names from constants or an allow-list.
- Do not use Intent extras, request parameters, or IPC input directly as permission strings.
- 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
actionrequest 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.