您的应用程序使用的内容提供程序具有不安全的 openFile 实现

Your app(s) are using a content provider with an unsafe implementation of openFile

我在 Playstore 上发布我的应用后收到了这封电子邮件:

您好Google Play 开发者,

我们审查了包名称为 com.example.myappname 的 [MyAppName],发现您的应用程序使用的软件包含用户安全漏洞。具有这些漏洞的应用可能会泄露用户信息或损坏用户的设备,并且可能会被视为违反了我们的恶意行为政策。

以下是您最近提交的问题列表和相应的 APK 版本。请尽快迁移您的应用以使用更新后的软件,并增加升级后APK的版本号。

您的应用程序使用的内容提供程序具有不安全的 openFile 实现。

要解决此问题,请按照这篇 Google 帮助中心文章中的步骤操作。

漏洞 APK 版本修复截止日期 路径遍历 您的应用程序使用的内容提供程序对 openFile 的实施不安全。

要解决此问题,请按照这篇 Google 帮助中心文章中的步骤操作。

1 2019 年 6 月 25 日 漏洞 APK 版本 修复截止日期 为确认您已正确升级,请将应用的更新版本提交到 Play 管理中心,并在 5 小时后回来查看。如果应用程序未正确更新,我们将显示一条警告消息。


我在我的应用程序中使用了 Realm 数据库、iText pdf 库、文件提供程序。我正在使用 FileProvider 使用 intent 从存储中打开 pdf 文件。

res>xml>provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="external_files"
        path="." />
</paths>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.appName">

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_icon"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_icon"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        ...

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>
    </application>

</manifest>

TemplatesFragment.java

File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyCvs/Templates/" + templateName);
        Uri uriPdf = FileProvider.getUriForFile(getActivity(), BuildConfig.APPLICATION_ID + ".provider", file);
        Intent target = new Intent(Intent.ACTION_VIEW);
        target.setDataAndType(uriPdf, "application/pdf");
        target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        target.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        Intent intent = Intent.createChooser(target, "Open File");
        try {
            startActivity(intent);
        } catch (Exception e) {
            // Instruct the user to install a PDF reader here, or something
            Toast.makeText(getActivity(), "" + e.getMessage(), Toast.LENGTH_SHORT).show();
        }

他们实际上提供了一个人需要知道的一切;见 support.google.com:

Implementations of openFile 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.

FileProvider 必须拒绝任何包含 ..Uri ...被视为 "exploitable"。

不要将 "." 放在 path 中,而是提供您要使用的文件夹的名称。

例如,如果您想要 access/use 下载文件夹,那么在 provider_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="downloads"
        path="Download/" />
</paths>