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
当 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);
}
}
参考¶
Google 帮助:Intent 重定向漏洞的修复。
通用弱点枚举:CWE-266。
通用弱点枚举:CWE-926。