ANDROID.LIFECYCLE.SV.FRAGMENTINJ
未经验证的片段类名
出于安全考虑,应用程序通常无法访问其他应用程序的敏感数据。在某些情况下,为方便重复使用功能,应用程序可以调用其他应用程序的组件(例如活动)。由于活动可以访问输入 Intent 的数据,因此错误的应用程序可以调用已导出活动并向其提供恶意数据。如果未在目标应用程序中对数据进行适当地消毒或验证,上述情况可能触发漏洞。
在 Android 4.3 Jelly Bean 和更早版本中发现了此类漏洞。
漏洞与风险
通过使用已导出的活动扩展了 PreferenceActivity 类的所有应用程序都会自动出现漏洞。恶意应用程序可以让 PreferenceActivity 加载存在漏洞的应用程序的任意 Fragment,该项通常在用户 Activity 内加载。之后,恶意应用程序便可对其进行控制。
使用 PreferenceActivity 的所有应用程序均存在该漏洞。
缓解与预防
Google 通过添加新的受保护 API PreferenceActivity.isValidFragment(在动态实例化片段之前调用)修补了 Android 4.4 KitKat。必须覆盖 isValidFragment 方法。
如果未调用 isValidFragment 方法进行验证,Klocwork 将报告错误。
示例 1
复制
public class MyActivity extends PreferenceActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final String initialFragment = getIntent().getStringExtra("EXTRA_SHOW_FRAGMENT");
final Fragment f = Fragment.instantiate(this, initialFragment, null);
final FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.replace(11, f);
transaction.commitAllowingStateLoss();
}
针对第 19 行报告 ANDROID.LIFECYCLE.SV.FRAGMENTINJ:意图来自应用程序外部。额外的信息用于实例化片段。在此期间未进行任何信息验证。
示例 2
复制
public class MyActivity extends PreferenceActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final String initialFragment = getIntent().getStringExtra("EXTRA_SHOW_FRAGMENT");
if (!isValidFragment(initialFragment)) {
throw new IllegalArgumentException("Invalid fragment for this activity");
}
final Fragment f = Fragment.instantiate(this, initialFragment, null);
final FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.replace(11, f);
transaction.commitAllowingStateLoss();
}
public boolean isValidFragment(final String name) {
//validate here …
}
不会在此处报告缺陷,因为已在第 15 行执行验证。