【缺陷周话】第56期:ContentProvider URI 注入
字数 1120 2025-08-18 11:39:04
ContentProvider URI 注入安全缺陷分析与防护指南
1. 缺陷概述
ContentProvider URI 注入是Android应用开发中常见的安全漏洞,属于CWE-89类缺陷(SQL命令中特殊元素的不当处理)。该漏洞允许攻击者通过构造恶意URI访问未经授权的数据或执行非预期的操作。
2. 漏洞原理
2.1 ContentProvider工作机制
- ContentProvider是Android四大组件之一,用于不同应用间的数据共享
- 通过URI标识数据资源,格式为:
content://authority/path/id - 提供标准的增删改查(CRUD)接口
2.2 注入产生原因
当应用程序:
- 直接使用用户输入构造查询URI
- 未对用户输入进行适当过滤和编码
- 动态拼接URI字符串
攻击者可通过注入特殊字符或路径片段来改变查询意图,访问非授权数据。
3. 漏洞示例分析
3.1 缺陷代码示例
// 获取用户输入
EditText et = (EditText) findViewById(R.id.editText1);
String msgId = et.getText().toString();
// 直接使用用户输入构造URI
Uri uri = Uri.parse("content://my.authority/messages/" + msgId);
// 执行查询
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
风险点:
- 直接拼接用户输入(msgId)到URI中
- 无任何输入验证或编码处理
- 攻击者可构造如
deleted等路径访问非预期数据
3.2 实际危害案例
- CVE-2019-14339:Canon PRINT应用因ContentProvider访问控制不当,导致攻击者可获取管理员密码和WPA2-PSK密钥等敏感信息
4. 防护方案
4.1 输入编码处理
// 对用户输入进行URI编码
String encodedMsgId = Uri.encode(msgId);
Uri uri = Uri.parse("content://my.authority/messages/" + encodedMsgId);
使用Uri.encode()方法对输入进行UTF-8编码,处理特殊字符。
4.2 白名单验证
// 定义合法ID白名单
Set<String> validIds = new HashSet<>(Arrays.asList("1", "2", "3"));
if(!validIds.contains(msgId)) {
throw new IllegalArgumentException("Invalid message ID");
}
适用于资源ID有限且已知的情况。
4.3 参数化查询
Uri baseUri = Uri.parse("content://my.authority/messages");
Uri uri = baseUri.buildUpon().appendPath(msgId).build();
// 使用参数化查询
String[] projection = null;
String selection = null;
String[] selectionArgs = null;
String sortOrder = null;
Cursor cursor = getContentResolver().query(
uri, projection, selection, selectionArgs, sortOrder);
4.4 权限控制
在AndroidManifest.xml中配置适当的权限:
<provider
android:name=".MyContentProvider"
android:authorities="my.authority"
android:exported="false"
android:permission="com.example.permission.ACCESS_PROVIDER"/>
5. 最佳实践
- 最小权限原则:ContentProvider应设置为
android:exported="false"除非必须跨应用共享 - 路径验证:实现
UriMatcher严格匹配合法URI模式 - 输入验证:
- 验证输入长度和格式
- 拒绝而非过滤可疑输入
- 日志与监控:记录异常查询尝试
- 安全测试:使用工具检测URI注入漏洞
6. 检测与修复
6.1 检测方法
- 静态分析:查找直接拼接用户输入构造URI的代码模式
- 动态测试:尝试注入特殊字符和路径遍历payload
6.2 修复验证
修复后应验证:
- 非法输入被正确拒绝
- 编码后的输入不会改变查询语义
- 权限检查有效
7. 相关资源
通过实施这些防护措施,可有效预防ContentProvider URI注入漏洞,保护Android应用数据安全。