CodeQL 文档

Intent URI 权限操纵

ID: java/android/intent-uri-permission-manipulation
Kind: path-problem
Security severity: 7.8
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-266
   - external/cwe/cwe-926
Query suites:
   - java-code-scanning.qls
   - java-security-extended.qls
   - java-security-and-quality.qls

单击以在 CodeQL 存储库中查看查询

当 Android 组件希望从 Activity 获得结果时,可以使用 startActivityForResult。然后,启动的 Activity 可以使用 setResult 向调用组件返回相应数据。

如果 Activity 获取传入的用户提供的 Intent 并直接通过 setResult 返回它而不进行任何检查,则应用程序可能会意外地授予对其内容提供程序的任意访问权限,即使它们未导出,只要它们配置了属性 android:grantUriPermissions="true"。这是因为攻击者向提供的 Intent 添加了适当的 URI 权限标志,一旦 Intent 被反射回来,这些标志就会生效。

建议

避免通过 setResult 返回用户提供的或不受信任的 Intent。改用新的 Intent。

如果需要使用接收到的 Intent,请确保它不包含 URI 权限标志,可以通过使用 Intent.getFlags 检查它们或使用 Intent.removeFlags 删除它们来实现。

示例

以下示例包含三个示例。在第一个示例中,获取用户提供的 Intent,并使用 setResult 直接返回,这是很危险的。在第二个示例中,创建一个新 Intent 以安全地返回所需数据。第三个示例演示了如何在使用获取的 Intent 返回数据给调用组件之前,通过移除危险标志来对其进行清理。

public class IntentUriPermissionManipulation extends Activity {

    // BAD: the user-provided Intent is returned as-is
    public void dangerous() {
        Intent intent = getIntent();
        intent.putExtra("result", "resultData");
        setResult(intent);
    }

    // GOOD: a new Intent is created and returned
    public void safe() {
        Intent intent = new Intent();
        intent.putExtra("result", "resultData");
        setResult(intent);
    }

    // GOOD: the user-provided Intent is sanitized before being returned
    public void sanitized() {
        Intent intent = getIntent();
        intent.putExtra("result", "resultData");
        intent.removeFlags(
                Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
        setResult(intent);
    }
}

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私