android - ContentProvider 路径遍历漏洞

标签 android android-contentprovider

Google 就 ContentProvider 中的路径遍历漏洞发出警告
https://support.google.com/faqs/answer/7496913

Implementations of openFile and openAssetFile in exported ContentProviders can be vulnerable if they do not properly validate incoming Uri parameters. A malicious app can supply a crafted Uri (for example, one that contains “/../”) to trick your app into returning a ParcelFileDescriptor for a file outside of the intended directory, thereby allowing the malicious app to access any file accessible to your app.


他们的例子(来自上面的链接):
public ParcelFileDescriptor openFile (Uri uri, String mode)
 throws FileNotFoundException {
 File f = new File(DIR, uri.getLastPathSegment());
  if (!f.getCanonicalPath().startsWith(DIR)) {
    throw new IllegalArgumentException();
  }
 return ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
}
DIR 指的是什么?我如何实现正确的修复?

最佳答案

DIR指您要从中共享文件的应用程序内部存储中的目录。
这可能是:

File fd = getContext().getFilesDir();
String DIR = fd.getAbsolutePath() + "/public";
(结果:/data/user/0/[APPLICATION_ID]/files/public)
修复:
要解决此问题,您必须确保攻击者无法使用包含路径遍历字符(例如“../”)的恶意 URI 访问内部存储中的意外文件。
(例如,/data/user/0/[APPLICATION_ID]/databases 中的数据库文件是“意外文件”。)
正如 Google 建议的那样,您可以通过检查文件的规范路径来做到这一点。规范路径是绝对的,不包含“。”或“..”了。 (如果文件的规范路径以您的目录路径开头,一切都很好。)
例子:
  • 恶意 URI:content://[APPLICATION_ID]/public/../../databases/database.db
  • 恶意路径:/data/user/0/[APPLICATION_ID]/files/public/../../databases/database.db
  • 规范路径:/data/user/0/[APPLICATION_ID]/databases/database.db

  • 所以,这是完整的修复:
    private String DIR; 
    
    @Override
    public boolean onCreate() {
        File fd = getContext().getFilesDir();
        DIR = fd.getAbsolutePath() + "/public";
        return true;
    }
    
    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode)
            throws FileNotFoundException {
        File f = new File(DIR, uri.getLastPathSegment());
        if (!f.getCanonicalPath().startsWith(DIR)) {
            throw new IllegalArgumentException();
        }
        return ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
    }
    
    (旁注: DIR 应该是 dir ,因为它不是常数。)

    关于android - ContentProvider 路径遍历漏洞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49812687/

    相关文章:

    java - 在 SQLite 中查询日期的月份部分

    android - 安全地限制对 FileProvider 的访问

    android - 如何通过 CursorLoader 使用 ContentProvider 的 insert() 方法将值正确地插入到 SQLite 数据库中?

    android - 如何在 xml 中引用自定义资源文件

    android - 如何在自己的对象空间上进行旋转?

    android - 单元测试Android,从资源中获取字符串

    java - 如何应对交互式 Linux 命令?

    android - IntentService 和 CursorLoader 同步问题

    android - 使用 ContactsContract.Contacts.Data

    android - 内容提供商是否是单个阻止实例?