CodeQL 文档

Android Intent 重定向

ID: java/android/intent-redirection
Kind: path-problem
Security severity: 7.5
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-926
   - external/cwe/cwe-940
Query suites:
   - java-code-scanning.qls
   - java-security-extended.qls
   - java-security-and-quality.qls

点击查看 CodeQL 存储库中的查询

如果一个导出的 Android 组件获取了一个用户提供的 Intent 并使用它来启动另一个组件,则可能会被利用来访问同一应用的私有、未导出组件,或者代表受害应用启动其他应用的组件。

建议

不要导出从用户提供的 Intent 启动其他组件的组件。可以通过在应用的 Android Manifest 中将 android:exported 属性设置为 false 将其设为私有。

如果无法做到这一点,请限制可以向受影响组件发送 Intent 的应用,或限制可以从此组件启动的组件。

示例

以下代码段包含三个示例。在第一个示例中,可以从外部提供的 forward_intent Intent 启动任意组件。在第二个示例中,首先检查 Intent 的目标组件以确保其安全。在第三个示例中,首先检查创建 Intent 的组件以确保其来自受信任的来源。

// BAD: A user-provided Intent is used to launch an arbitrary component
Intent forwardIntent = (Intent) getIntent().getParcelableExtra("forward_intent");
startActivity(forwardIntent);

// GOOD: The destination component is checked before launching it
Intent forwardIntent = (Intent) getIntent().getParcelableExtra("forward_intent");
ComponentName destinationComponent = forwardIntent.resolveActivity(getPackageManager());
if (destinationComponent.getPackageName().equals("safe.package") && 
    destinationComponent.getClassName().equals("SafeClass")) {
    startActivity(forwardIntent);
}

// GOOD: The component that sent the Intent is checked before launching the destination component
Intent forwardIntent = (Intent) getIntent().getParcelableExtra("forward_intent");
ComponentName originComponent = getCallingActivity();
if (originComponent.getPackageName().equals("trusted.package") && originComponent.getClassName().equals("TrustedClass")) {
    startActivity(forwardIntent);
}

参考

  • ©GitHub 公司
  • 条款
  • 隐私