【缺陷周话】第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 注入产生原因

当应用程序:

  1. 直接使用用户输入构造查询URI
  2. 未对用户输入进行适当过滤和编码
  3. 动态拼接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. 最佳实践

  1. 最小权限原则:ContentProvider应设置为android:exported="false"除非必须跨应用共享
  2. 路径验证:实现UriMatcher严格匹配合法URI模式
  3. 输入验证
    • 验证输入长度和格式
    • 拒绝而非过滤可疑输入
  4. 日志与监控:记录异常查询尝试
  5. 安全测试:使用工具检测URI注入漏洞

6. 检测与修复

6.1 检测方法

  • 静态分析:查找直接拼接用户输入构造URI的代码模式
  • 动态测试:尝试注入特殊字符和路径遍历payload

6.2 修复验证

修复后应验证:

  1. 非法输入被正确拒绝
  2. 编码后的输入不会改变查询语义
  3. 权限检查有效

7. 相关资源

通过实施这些防护措施,可有效预防ContentProvider URI注入漏洞,保护Android应用数据安全。

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 缺陷代码示例 风险点 : 直接拼接用户输入(msgId)到URI中 无任何输入验证或编码处理 攻击者可构造如 deleted 等路径访问非预期数据 3.2 实际危害案例 CVE-2019-14339 :Canon PRINT应用因ContentProvider访问控制不当,导致攻击者可获取管理员密码和WPA2-PSK密钥等敏感信息 4. 防护方案 4.1 输入编码处理 使用 Uri.encode() 方法对输入进行UTF-8编码,处理特殊字符。 4.2 白名单验证 适用于资源ID有限且已知的情况。 4.3 参数化查询 4.4 权限控制 在AndroidManifest.xml中配置适当的权限: 5. 最佳实践 最小权限原则 :ContentProvider应设置为 android:exported="false" 除非必须跨应用共享 路径验证 :实现 UriMatcher 严格匹配合法URI模式 输入验证 : 验证输入长度和格式 拒绝而非过滤可疑输入 日志与监控 :记录异常查询尝试 安全测试 :使用工具检测URI注入漏洞 6. 检测与修复 6.1 检测方法 静态分析:查找直接拼接用户输入构造URI的代码模式 动态测试:尝试注入特殊字符和路径遍历payload 6.2 修复验证 修复后应验证: 非法输入被正确拒绝 编码后的输入不会改变查询语义 权限检查有效 7. 相关资源 OWASP Mobile Top 10 Android ContentProvider安全指南 CWE-89: SQL Injection 通过实施这些防护措施,可有效预防ContentProvider URI注入漏洞,保护Android应用数据安全。