Description
Passing an externally supplied class name to Fragment.instantiate or a similar dynamic Fragment API may let an attacker load an unintended Fragment. In an exported Activity, a lower-privileged app may gain access to internal screens or sensitive operations.
Potential impact
- Exposure of internal Fragments or settings screens
- Access to functions without the required permission checks
- Display of sensitive data or changes to application state
Remediation
- Do not use external input directly as a Fragment class name.
- Map only allowed Fragment identifiers through an allow-list.
- With
PreferenceActivity, makeisValidFragmentreturntrueonly for explicitly allowed names. Check user permissions even on permitted screens, and avoid exporting Activities unnecessarily.
Examples
These excerpts belong inside an existing Activity. SettingsFragment is an application-defined permitted destination; screen-access authorization remains necessary.
Before
java
String fragment = getIntent().getStringExtra("fragment");
Fragment.instantiate(this, fragment);
After
java
Map<String, String> allowed = Map.of("settings", SettingsFragment.class.getName());
String fragment = allowed.get(getIntent().getStringExtra("fragment"));
if (fragment != null) {
Fragment.instantiate(this, fragment);
}
Explanation:
- Before: Passes an external class name to
Fragment.instantiate, potentially loading an unintended Fragment in an exported Activity. - After: Maps a permitted identifier to a known Fragment name. Statically constructed Fragment instances are another option.