以编程方式更改清单文件 - Android自定义权限

12

目前的Android权限系统引起以下问题:

应用程序A定义了自定义权限:

com.package.permission.READ_APP_DATA

当安装应用程序B并声明自定义权限时,它将被授予。

然而,如果应用程序A在应用程序B之后安装,则不会向应用程序B授予权限。

虽然这可能不是常见情况,因为应用程序B通常是应用程序A的插件,但对于我的应用程序来说确实会发生。

由于超级用户应用程序同意引入全局自定义权限android.permission.ACCESS_SUPERUSER,如果用户决定切换超级用户应用程序,则可能会出现大问题。

为了处理此问题,我打算在我即将开始声明的自定义权限中使用以下代码:

checkPermissions(this, getCallingActivity().getPackageName()); // get the package name from the sender first

private boolean checkPermissions(Context context, String callingPackage) {

    final List<PackageInfo> apps = context.getPackageManager().getInstalledPackages(PackageManager.GET_PERMISSIONS);

    for (PackageInfo pi : apps) {

        if (pi.packageName.equals(callingPackage)) {

            String[] permissions = pi.requestedPermissions;

            if (permissions != null) {
                for (String permission : permissions) {
                    if (permission.equals("com.package.permission.READ_APP_DATA")) {
                        return true;
                    }
                }
            }
        }
    }
    return false;

根据这个问题的标题:这种方法“安全”吗?或者说,在应用程序被安装后,是否存在一种方式/根黑客可以修改其清单并将权限以编程方式“添加”到应用程序B中?


1
然而,如果应用程序A在应用程序B之后安装,则不会向应用程序B授予权限。请确保两个应用程序都具有相同的<permission>元素,特别是如果这是一个signature级别的权限。 - CommonsWare
1
我相信这已经是我正在做的事情了 - 你的问题表明只有应用程序A具有<permission>元素,而应用程序B只有<uses-permission>元素。我建议在应用程序B中也添加<permission>元素,这样安装顺序就不再重要了。 - CommonsWare
1
尽管以这种方式要求第三方开发人员声明我的自定义权限感觉有点令人不安,但正如我所指出的那样,最好使用“签名”级别的权限,因此所有受影响的应用程序都是您自己的。权限系统的不幸限制之一是,谁先进入就可以定义权限在用户看来的外观(标签和描述)。虽然你无能为力,但你仍需接受这个事实。 - CommonsWare
4
关于你上面的技巧,我从未见过有人这样做。实际上,我的最初反应是它不会起作用,直到我意识到requestedPermissions包括未授予的权限。鉴于此,我没有看到任何漏洞,但我认为我有与你发布这个问题时相同的忧虑。:-) 如果没别的,确保你将其测试回到你的minSdkVersion,因为这感觉像是Android的行为可能在多年后发生了变化的那种领域。 - CommonsWare
2
在Android L上,在两个应用程序中声明自定义权限不再起作用(您会收到安装错误:INSTALL_FAILED_DUPLICATE_PERMISSION)。他们似乎已经关闭了这个漏洞(请参见http://commonsware.com/blog/2014/02/12/vulnerabilities-custom-permissions.html)。 - Emanuel Moecklin
显示剩余5条评论
2个回答

10

我不确定我是否理解得正确,因为我不知道在安装后如何将权限添加到清单中与您上面发布的代码有什么关联。但是回答您的最后一段:

不容易。用户必须在设备上安装一个mod,可以在应用程序请求权限时即时授予任意权限。如果我没记错,清单文件本身只在安装时解析。

因此,在mod中使用的是更改com.android.server.pm.PackageManagerService类中的方法grantPermissionsLPw

它用于授予启动器android.permission.EXPAND_STATUS_BAR权限,而它没有在其清单中声明。

虽然我不确定这是否会用于您的应用程序。但总而言之:如果用户想要授予应用程序任意自定义权限:是可能的。

更新

当然,我可以进一步阐述。我可以看到发生两种情况

1. 静态mod

上述提到的类驻留在services.jar中。我们知道,像这样的文件可以反编译,修改和重新编译。实际上,对于这个文件来说,它是相当容易编辑的。我不知道是否有直接在手机上进行此操作的方法,但我认为这是可能的。只是不那么可行,因为需要大量的处理能力才能提供广泛的解决方案。攻击者不能仅提供通用文件。这些文件因设备而异,并且在固件版本之间也会发生变化。攻击者要么需要提供大量修补的文件,要么通过上传到服务器,拼接,重新下载和安装来进行实时修补。如果您问我的话,这种情况并不太可能。

2. 动态mod

有多个框架可用于在操作过程中修改进程。其中最受欢迎的是Xposed Framework。基本上,它是一个修补过的app_process和相应的API,利用Reflection来改变运行中的进程。现在,攻击者可以将他的应用与此框架捆绑,并拥有root访问权限,悄悄地安装它。有了root访问权限,他甚至可以自己启用模块,而这通常需要用户交互。一旦启用了这样的模块,攻击者就可以钩入上述方法并更改所请求的权限。他会通过获取保存所请求权限的对象字段、添加他需要的权限,然后运行原始方法,从而添加原来定义的权限。

请注意,这两种情况都需要用户自己安装恶意应用程序。您没有提到您的应用程序是做什么的,因此我无法更多地帮助您评估风险。我只能说,攻击者确实可以做出这样的事情。


谢谢你的回答 - 你能详细说明一下这个模块是如何工作的吗?这会帮助我理解“风险”。 - brandall
请查看上面的更新。类名也已更正。如果您有任何问题,请随时提问。 - langerhans
1
感谢您的更新,这真的很有帮助,并且提供了一些好的相关阅读。我会回来标记您的答案为正确,并因您的努力授予奖励。 - brandall

0

我发现一个问题,如果在安装应用程序B之前安装了应用程序A,并且在应用程序A中未声明<permission>元素,则用户将永远不会看到权限请求。但是,如果您确实需要在应用程序A中使用<permission>元素,则可以使用类似的方法来验证向用户显示的标签和描述是否准确。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接