Movatterモバイル変換


[0]ホーム

URL:


CodeQL documentation
CodeQL resources

Android fragment injection

ID: java/android/fragment-injectionKind: path-problemSecurity severity: 9.8Severity: errorPrecision: highTags:   - security   - external/cwe/cwe-470Query suites:   - java-code-scanning.qls   - java-security-extended.qls   - java-security-and-quality.qls

Click to see the query in the CodeQL repository

When fragments are instantiated with externally provided names, this exposes any exported activity that dynamically creates and hosts the fragment to fragment injection. A malicious application could provide the name of an arbitrary fragment, even one not designed to be externally accessible, and inject it into the activity. This can bypass access controls and expose the application to unintended effects.

Fragments are reusable parts of an Android application’s user interface. Even though a fragment controls its own lifecycle and layout, and handles its input events, it cannot exist on its own: it must be hosted either by an activity or another fragment. This means that, normally, a fragment will be accessible by third-party applications (that is, exported) only if its hosting activity is itself exported.

Recommendation

In general, do not instantiate classes (including fragments) with user-provided names unless the name has been properly validated. Also, if an exported activity is extending thePreferenceActivity class, make sure that theisValidFragment method is overriden and only returnstrue when the providedfragmentName points to an intended fragment.

Example

The following example shows two cases: in the first one, untrusted data is used to instantiate and add a fragment to an activity, while in the second one, a fragment is safely added with a static name.

publicclassMyActivityextendsFragmentActivity{@OverrideprotectedvoidonCreate(BundlesavedInstance){try{super.onCreate(savedInstance);// BAD: Fragment instantiated from user input without validation{StringfName=getIntent().getStringExtra("fragmentName");getFragmentManager().beginTransaction().replace(com.android.internal.R.id.prefs,Fragment.instantiate(this,fName,null)).commit();}// GOOD: Fragment instantiated statically{getFragmentManager().beginTransaction().replace(com.android.internal.R.id.prefs,newMyFragment()).commit();}}catch(Exceptione){}}}

The next example shows two activities that extendPreferenceActivity. The first activity overridesisValidFragment, but it wrongly returnstrue unconditionally. The second activity correctly overridesisValidFragment so that it only returnstrue whenfragmentName is a trusted fragment name.

classUnsafeActivityextendsPreferenceActivity{@OverrideprotectedbooleanisValidFragment(StringfragmentName){// BAD: any Fragment name can be provided.returntrue;}}classSafeActivityextendsPreferenceActivity{@OverrideprotectedbooleanisValidFragment(StringfragmentName){// Good: only trusted Fragment names are allowed.returnSafeFragment1.class.getName().equals(fragmentName)||SafeFragment2.class.getName().equals(fragmentName)||SafeFragment3.class.getName().equals(fragmentName);}}

References


[8]ページ先頭

©2009-2025 Movatter.jp