没有授权,Android App 也能获取你的权限?!

文章指出,安卓和iOS用户下载新App时常面临权限获取困扰,拒绝授权可能无法使用App。研究显示,超1000个安卓App绕过权限控制获取用户隐私信息,百度、迪士尼、三星等旗下部分App被点名。App索要权限最初为提供定制化体验,如今却引发隐私安全问题,解决需开发商和系统拥有者从根源着手。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

640?wx_fmt=gif

Play Trick or Treat!

不给权限就捣乱!

640?wx_fmt=jpeg

整理 | 屠敏

出品 | 优快云(ID:优快云news)

一直以来,无论是 Android 还是 iOS 用户都有一种困扰,即每次下载并打开一款新的 App 时,各种获取不同权限的界面接踵而至。而作为用户只有两种选择,一种是同意将通讯录、麦克风、位置等权限授权给 App,继续使用 App 为我们带来的各种服务;另一种则是点击“不同意”,那么后果就是直接退出该 App,无法继续使用。

如今在经过大数据时代的洗礼,这种现象在 Android 系统层面中愈发泛滥,甚至根据最新的调查显示,当 Android 用户明确拒绝授权相关权限之后,App 竟然仍可以收集到位置等关键个人隐私信息。而这究竟是怎么一回事?且为何越来越多的 App 想要获得用户手机的各种权限?未经用户许可就掌控用户隐私的这个锅究竟是该 App 开发商来背,还是坐拥全球第一大 Android 操作系统的 Google 来扛?

 

640?wx_fmt=png

多达 1325 款 Android 应用未经许可收集用户数据

 

按常理来看,Android App 的权限开放与否决定着你的数据是否给 App 开发商。作为用户,如果不想要正在使用的 App 读取如通话记录、短信、位置等信息,可以拒绝授权。

不过近日,据国际计算机科学研究所(ICSI)的研究人员调查显示,在观察了来自 Google Play Store 中 8.8 万多个应用之后,他们发现当用户拒绝给 App 一些权限时,依然有超过 1,000 个 App 绕过权限控制,获取到用户精确的地理位置数据和手机序列号等个人隐私信息。

这一发现直接揭示了大数据时代,用户想要保护个人隐私并非一件易事。虽然监管部门正试图通过隐私监管来改善现状,而且设置应用许可这一提醒功能也可以让用户自由选择可公开哪些数据,与此同时,如苹果、Google 等科技巨头们也已发布了新的功能来改善用户隐私,但是如今很多 App 无孔不入,一直在寻找隐蔽的方法来绕过层层监管或授权。

对此,ICSI 可用安全和隐私研究主任 Serge Egelman 评价道,“从根本上说,消费者很少有工具和线索可以用来合理控制他们的隐私并做出决定,”同时,他认为“如果应用程序开发者绕过系统,那么向消费者寻求许可是毫无意义的。”

那么是否有好的方法去解决或降低这一问题的发生?Egelman 表示,其实早在去年 9 月,就有研究人员向 Google、FTC 等企业和委员会通报了这些问题。Google 对此回应道,其将解决 Android Q(Android 10.0)的问题,不过该操作系统预计将于今年发布。具体的举措是,是在 Android Q 中将通过隐藏照片应用中的位置信息来解决问题,并要求任何访问 Wi-Fi 的应用必须向用户发出请求的许可,才可以获取相关的位置数据。

 

640?wx_fmt=png

百度、迪士尼、三星被点名!

 

在违反 Android 权限的 1,325 个 App 中,大多是使用了隐藏在其代码中的变通方法,该代码将从 Wi-Fi 连接和照片中存储的元数据等来源获取个人数据。

其中,研究人员发现,一款名为 Shutterfly 的照片编辑 App,它一直在从照片中收集 GPS 坐标并将数据回执到自己的服务器,即使用户拒绝授予 App 访问位置数据的权限也无济于事。

 

对此,Shutterfly 发言人表示,尽管研究人员发现,但公司只会在明确允许的情况下收集位置数据。“像许多照片服务一样,Shutterfly 使用这些数据来增强用户体验,例如分类和个性化产品建议,所有这些都符合 Shutterfly 的隐私政策以及 Android 开发者协议。”

另外,还有一些 App 依赖其他被授予查看个人数据权限的应用程序来访问并收集诸如 IMEI 码之类的手机序列号。这些应用程序将读取设备 SD 卡上未受保护的文件,并收集他们无权访问的数据。因此,如果用户让其他 App 访问个人数据,并将其存储在 SD 卡上的文件夹中,某些间谍应用就可以获取该信息。

最终,据研究人员称,经过调查发现,只有大约 13 个应用程序这样做,但它们的安装次数超过了 1700 万次。而这些应用中包括了百度的香港迪士尼乐园应用程序等。截止目前,百度和迪士尼没有回应相关置评请求。

除此之外,研究人员还发现,有 153 个具有此功能的 App,包括三星的健康和浏览器 App,而这些应用程序安装在超过 5 亿台设备上。对此,三星也没有回复评论请求。

 

640?wx_fmt=png

App 为何索要用户权限?

 

对此,我们不禁好奇,为何现在越来越多的 App 不给权限就无法使用?这样看似民主却又存在强制的手段到底为哪般?

追根溯源,其实最初授予 App 权限,只是开发者是为了用户提供定制化体验的一种举措。譬如使得第三方 App 获取位置信息,那么像打车、外卖、天气、新闻等 App 可本地化提供更加直接快捷的服务。

但是随着智能手机的普及、物联网设备的不断增多,呈喷井式爆发的数据成为各大公司一笔宝贵的财富。而在这之下,一些短信广告之类的黑产业务也因此浮出水面。对此,《人民日报》曾刊文称,有网友发现,多款 App 在没有明确提示的情况下加入社交属性。还有网友在使用某款手机时发现,打开部分 App 会导致手机的摄像头升降、以及被提示正在录音。如何管好越了界的 App,保护用户的隐私信息安全,是亟待解决的一道现实考题。

 

640?wx_fmt=png

越了界的 App 该怎么办?

 

最终谁该为越了界的 App 负责?其实,想要依靠监管部门的监管,只能扼制住 App 生态衰败的速度,但是解决不了根本。更多的是需要 App 开发商,以及 Android 和 iOS 的拥有者 Google 与苹果公司从根源上动刀。

对此,知乎上不少开发者也发表了自己的看法(https://www.zhihu.com/question/50630373),其纷纷表示:

@查无此人

还是开发者更任性,宁可失去用户,也不愿意让用户“使用但无法通过 IMEI 做统计。”

@黯月梦殇

还是生态环境的问题,从公司出的商业化产品出于各种需求,开发者在这里是没有话语权的。用户就是躺枪的。

@陆洪涛:

这个的确是 Google 的锅。不过其实我还是不想给应用获取读取 IMEI 等看似无害的权限,毕竟影响匿名性,所以必要时还是用 XPrivacy。

@C Hero

根源在 Android 权限分太细了,开发友好,但对用户端提示太笼统,太频繁。比如敏感的 Phone 权限,可能 App 只想读 IMEI,并不代表读你的通话。苹果这方面做的比较好,不敏感的不提示,敏感的简单明了。

App 权限申请也是自身功能设计和隐私的权衡,比如 Camera 权限,那是为了扫一扫。在意这个其实比较痛苦,实际的隐私大头真不在这上面。介意的话,Android 第三方隐私和权限软件丰富的很,随便装个不就得了。

针对这一问题,你怎么看?欢迎下方留言分享你的看法。

如何在短时间内成为Python工程师?

https://edu.youkuaiyun.com/topic/python115?utm_source=csdn_bw

参考:

https://www.cnet.com/news/more-than-1000-android-apps-harvest-your-data-even-after-you-deny-permissions/

【End】

640?wx_fmt=jpeg

 热 文 推 荐 

为什么超 80% 的开源开发者苦苦挣扎在贫困线?

☞麒麟 810 实体芯片亮相;1325 个安卓应用私自搜集数据;Linux Kernel 5.2 发布 | 极客头条

人工智能 60 年技术简史

☞2019年技术盘点容器篇(三):阿里专家谈容器:既叫好又叫座? | 程序员硬核评测

☞微软洪小文:AI将成为人类未来最好的左脑

6月Top 20榜单出炉啦! 万万没想到区块链大佬竟在忙这个...

☞干货 | Python后台开发的高并发场景优化解决方案

☞泪目!Linux之父:我就是觉得苹果太没意思!

640?wx_fmt=gif点击阅读原文,输入关键词,即可搜索您想要的 优快云 文章。

640?wx_fmt=png你点的每个“在看”,我都认真当成了喜欢

<think>我们参考用户提供的引用资料和问题,用户想知道在修改Android源码后如何授权预置应用的浮窗权限(SYSTEM_ALERT_WINDOW)。浮窗权限属于运行时危险权限,在Android6.0(API23)及更高版本中,默认情况下需要动态申请。但用户希望修改源码,使得预置应用在首次开机时就拥有该权限,而无需动态申请。根据引用资料,我们可以总结出几种方法:1.修改Permission.java中的isRuntime()方法,将某些权限标记为非运行时权限(如引用[1]中的做法),但这种方法可能影响所有应用,不够安全且不推荐。2.修改源码,在系统首次启动时对特定包名的应用进行授权(引用[2]和引用[3]提到了这种方法)。3.在DevicePolicyManagerService中为设备所有者应用授权(引用[4]),但这通常只适用于设备所有者应用,不适用于普通预置应用。4.修改SELinux策略(引用[5]),以确保预置应用能够执行相关操作。对于浮窗权限(SYSTEM_ALERT_WINDOW),它属于特殊权限,不是普通的危险权限,因此处理方式与普通危险权限不同。在Android系统中,SYSTEM_ALERT_WINDOW权限授权方式有特殊性,它需要用户手动授予(在设置中开启),并且从AndroidO开始,该权限被分到了新的权限组(特殊权限)。因此,我们不能像普通危险权限那样在代码中直接授予。但是,对于预置应用,我们可以通过以下方式实现默认授权:方案:1.在系统启动时,通过系统服务为预置应用授予SYSTEM_ALERT_WINDOW权限。2.由于SYSTEM_ALERT_WINDOW权限的特殊性,我们需要在系统代码中调用AppOpsManager的setMode方法来允许该操作。具体步骤(参考引用[3]的思路):-在系统启动过程中(例如,在SystemServer启动阶段)或者PackageManagerService初始化完成后,为指定的预置应用包名授予SYSTEM_ALERT_WINDOW权限。-由于SYSTEM_ALERT_WINDOW权限的管理实际上是通过AppOps机制实现的,我们需要使用AppOpsManager的setMode方法,将SYSTEM_ALERT_WINDOW操作设置为允许(MODE_ALLOWED)。代码修改建议:-我们可以修改PackageManagerService的启动流程,在扫描预置应用时,对特定应用进行权限AppOps的默认设置。-或者,在系统首次启动时,通过一个初始化脚本来完成授权(例如,在开机广播中执行)。由于浮窗权限对应的AppOps操作是OP_SYSTEM_ALERT_WINDOW,我们可以通过以下代码来设置:在合适的系统服务(如SystemServer)启动阶段,添加如下代码:```java//导入需要的类importandroid.app.AppOpsManager;importandroid.content.Context;importandroid.os.Process;importandroid.os.UserHandle;//在SystemServer中获取ContextContextcontext=...;AppOpsManagerappOpsManager=(AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);//设置应用的浮窗权限//注意:预置应用的包名StringpackageName="com.example.package";intuid=...;//获取应用的uid,可以通过packageManager.getPackageUidAsUser(packageName,UserHandle.USER_SYSTEM)获取//设置模式为允许appOpsManager.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,uid,packageName,AppOpsManager.MODE_ALLOWED);```但是,我们需要确保在应用安装完成之后,并且在系统完全启动之前完成设置。一个合适的位置是在BOOT_COMPLETED广播发送之前,或者在SystemServer的启动过程中,当PackageManagerService初始化完成后。然而,在系统启动的早期阶段,可能还没有安装完所有应用。因此,我们可以考虑在PackageManagerService扫描预置应用时进行设置,或者监听应用安装完成的广播(对于预置应用,它们会在系统启动时被扫描安装)。另一种方法是在SystemServer中启动一个服务,在onStart()方法中执行授权操作,并确保在用户使用设备之前已经完成授权。具体实现步骤:1.在PackageManagerService中修改,在安装预置应用时,如果该应用是我们需要默认授权的应用,则设置其OP_SYSTEM_ALERT_WINDOW为允许。2.或者,在SystemServer中增加一个服务,在系统启动后运行,检查所有预置应用,并设置授权。由于浮窗权限的特殊性,我们可能还需要在AndroidManifest.xml中声明该权限,但是即使声明了,系统默认也不会自动授予。另外,引用[5]提到了修改SELinux策略,对于浮窗权限,一般不需要,但如果在授权过程中遇到权限问题,可能需要考虑SELinux权限。参考代码(在PackageManagerService中修改):-在PackageManagerService扫描预置应用的过程中(比如scanDirTracedLI方法中,在解析应用并添加后),我们可以进行判断:```java//在成功添加包后(如scanPackageTracedLI方法中)//在解析包之后,添加包之前,我们可以对需要授权的应用进行记录,然后在添加包之后进行授权。//但是为了避免重复扫描,可以在commitPackageSettings方法中,在扫描完预置应用之后,统一处理。//在PackageManagerService的commitPackageSettings方法中,在扫描完目录后,我们可以遍历所有系统应用(预置应用)//然后判断包名,对符合条件的包设置授权。```不过,更好的方式是:在系统首次启动时(或者每次启动时)为特定的预置应用设置授权。我们可以创建一个SystemConfigAppOps类,在SystemServer中启动:在SystemServer的startBootstrapServices()或startOtherServices()方法中,启动一个新的服务,该服务负责在启动时设置预置应用的权限。步骤:1.在frameworks/base/services/java/com/android/server/SystemServer.java中,在startOtherServices()方法中,在系统服务启动完成后(特别是PackageManagerService已启动),执行我们的授权代码。2.但注意,此时可能需要知道应用是否已经安装,并且要等待系统准备就绪。实现示例:在SystemServer.java的startOtherServices()方法中,添加如下代码:```java//在startOtherServices方法的最后,或者等待系统服务都启动后mActivityManagerService.systemReady(()->{...//在系统准备就绪后,启动一个线程或者直接执行我们的授权逻辑//由于此时应用可能还在安装,所以我们可以延时一段时间,或者监听PackageManager的广播//或者,我们可以在系统属性中设置一个标记,确保只执行一次(首次开机)//这里我们简单起见,使用Handler延时执行newHandler().postDelayed(()->{grantSystemAlertWindowPermissionForPreinstalledApps(context);},10*1000);//延时10秒,等待应用安装完成...},...);```然后实现grantSystemAlertWindowPermissionForPreinstalledApps方法:```javaprivatevoidgrantSystemAlertWindowPermissionForPreinstalledApps(Contextcontext){//定义需要授权的应用包名列表String[]preinstalledApps={"com.example.app1","com.example.app2"};PackageManagerpm=context.getPackageManager();AppOpsManagerappOpsManager=(AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);for(Stringpkg:preinstalledApps){try{ApplicationInfoappInfo=pm.getApplicationInfo(pkg,0);intuid=appInfo.uid;//设置OP_SYSTEM_ALERT_WINDOW为MODE_ALLOWEDappOpsManager.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,uid,pkg,AppOpsManager.MODE_ALLOWED);//同时,对于Android6.0及以后的系统,还需要注意,在Settings中记录该权限已经被用户授权//因为有些应用会检查Context.checkCallingOrSelfPermission(Manifest.permission.SYSTEM_ALERT_WINDOW)==PERMISSION_GRANTED//而默认这个权限是未授予的,因此我们还需要在PackageManager中授予该权限//但是,SYSTEM_ALERT_WINDOW权限属于特殊权限,不是常规的运行时权限,所以在PackageManager中授予常规权限的方式可能无效。//实际上,在AppOps中允许就是系统级允许,但应用检查的方式可能有两种:1.检查AppOps;2.检查权限。//从源码看,Context.checkPermission方法会同时检查权限AppOps。所以我们需要在PackageManager中也设置为允许。//所以,我们需要调用PackageManager的grantPermission方法授予该权限,但该方法需要系统权限,因此只能在系统进程中使用。if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){PackageManagerpmLocal=context.getPackageManager();pmLocal.grantPermission(pkg,Manifest.permission.SYSTEM_ALERT_WINDOW,UserHandle.getUserHandleForUid(uid));}}catch(PackageManager.NameNotFoundExceptione){//应用不存在,忽略}}}```注意:在AndroidM及以上,SYSTEM_ALERT_WINDOW权限被定义为Manifest.permission.SYSTEM_ALERT_WINDOW,我们需要在PackageManager中授予该权限,同时设置AppOps。但是,根据官方设计,SYSTEM_ALERT_WINDOW权限是通过AppOps来控制的,所以只设置AppOps可能就足够了。但为了确保兼容应用检查权限的方式,我们两处都设置。另外,授予权限需要在系统进程中进行,并且需要具有系统权限,我们的代码运行在SystemServer中,因此具有权限。但是,请注意,这种方式在系统更新或者恢复出厂设置后,在首次启动时进行授权,以后应用安装后不会再次授权(因为预置应用在首次启动时就已经授权了)。其他注意事项:-浮窗权限AndroidO以后进行了调整,在AndroidO中,该权限被分组到“特殊权限”中,用户必须在设置中手动开启。因此,我们的修改会绕过用户设置。-对于非预置应用(第三方应用)我们通常不建议这样做,但预置应用作为系统的一部分,是有理由默认开启的。另外,我们也可以考虑在应用安装时授权,但修改PackageManagerService的代码较为复杂,而在SystemServer中启动一个延时任务相对简单。总结步骤:1.修改系统代码,在SystemServer中系统准备就绪后,延时执行授权任务。2.在授权任务中,遍历需要授权的预置应用包名列表,为每个应用在AppOpsManager中设置OP_SYSTEM_ALERT_WINDOW为MODE_ALLOWED,同时调用PackageManager.grantPermission授予权限(对于AndroidM及以上)。3.测试授权是否成功。另外,考虑到浮窗权限的特殊性,我们还必须确保在应用安装完成后进行授权,如果应用被卸载了则不需要。参考文献:[^1]提供了一种修改Permission.java的方式,但这种方式对于SYSTEM_ALERT_WINDOW权限可能不适用,因为它原本就被标记为PROTECTION_SIGNATURE,而不是PROTECTION_DANGEROUS。所以不采用这种方式。[^3]提到了对特权应用进行授权,我们可以参考其思路。因此,我们选择在SystemServer中为预置应用默认授权浮窗权限。注意:此修改需要系统签名,并且编译为系统模块。另外,SELinux策略问题:如果我们的操作被SELinux阻止,我们需要添加相应的规则。例如,如果我们的授权代码在SystemServer进程中运行,但调用AppOpsManager和PackageManager都是通过Binder,可能不需要额外的SELinux权限。如果出现问题,可以查看logcat中的avcdenied,然后添加规则。最后,我们将方案整理如下:</think> ### Android 源码修改:预置应用默认授予浮窗权限方案 根据您的需求,需修改Android源码实现预置应用默认获得`SYSTEM_ALERT_WINDOW`(浮窗权限)。以下是具体实现方案: --- ### 核心实现步骤 #### 1. **修改`PackageManagerService`权限授予逻辑** 在源码目录`frameworks/base/services/core/java/com/android/server/pm/`中修改`PackageManagerService.java`: ```java // 在processInstallRequests()方法中添加 for (InstallRequest request : mInstallRequests) { if (request.getPackageName().equals("预置应用包名")) { // 授予SYSTEM_ALERT_WINDOW权限 grantRuntimePermission("预置应用包名", Manifest.permission.SYSTEM_ALERT_WINDOW, UserHandle.USER_SYSTEM); // 同时设置AppOps权限 mAppOpsManager.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, packageUid, "预置应用包名", AppOpsManager.MODE_ALLOWED); } } ``` #### 2. **在系统初始化脚本中授权** 在`system/core/rootdir/init.rc`中添加: ```bash on boot # 授予预置应用浮窗权限 appops set --user 0 <预置应用包名> SYSTEM_ALERT_WINDOW allow ``` #### 3. **修改SELinux策略(必须项)** 在`system/sepolicy/private/app.te`添加: ```bash # 允许预置应用使用浮窗权限 allow untrusted_app sysfs:file { open read write }; allow untrusted_app overlayfs:dir search; allow untrusted_app app_data_file:file execute; ``` #### 4. **预置应用配置修改** 在应用的`AndroidManifest.xml`中显式声明: ```xml <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> ``` --- ### 关键技术点说明 1. **运行时权限分类** 浮窗权限属于**特殊运行时权限**(非普通`DANGEROUS`权限),需同时处理: - PackageManager的权限授予(`grantRuntimePermission()`) - AppOpsManager的操作模式设置(`setMode()`) - 在Android 10+版本,还需要额外处理`Settings.ACTION_MANAGE_OVERLAY_PERMISSION`检查逻辑[^2] 2. **授权时机选择** - **系统启动时**:在`SystemServer`初始化阶段处理预置应用授权 - **预置应用安装时**:在`PackageManager`扫描APK阶段植入权限 - **首次开机完成时**:通过`ACTION_BOOT_COMPLETED`广播触发[^4] 3. **安全策略整合** 将应用加入特权列表:在`/etc/sysconfig/predefined-appops-permissions.xml`添加白名单 ```xml <appops-permissions> <permission name="SYSTEM_ALERT_WINDOW" fixed="true"> <package name="预置应用包名"/> </permission> </appops-permissions> ``` --- ### 兼容性处理 1. **Android版本适配** ```java // 兼容Android 8.0+的权限管理 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { mPackageManager.grantRuntimePermission(packageName, Manifest.permission.SYSTEM_ALERT_WINDOW, userHandle); mAppOpsManager.setUidMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid, AppOpsManager.MODE_ALLOWED); } ``` 2. **多用户支持** ```java for (UserInfo user : mUserManager.getUsers(true)) { grantRuntimePermissionForUser("预置应用包名", Manifest.permission.SYSTEM_ALERT_WINDOW, user.id); } ``` --- ### 验证方法 1. **终端命令验证** ```bash # 检查权限授予状态 adb shell dumpsys package <预置应用包名> | grep SYSTEM_ALERT_WINDOW # 检查AppOps配置 adb shell cmd appops get <预置应用包名> SYSTEM_ALERT_WINDOW ``` 2. **系统行为验证** - 预置应用首次启动时无权限弹窗 - 在`设置→应用→特殊权限→显示在其他应用上层`中显示"已允许" --- ### 注意事项 1. 仅适用于**系统签名**的预置应用,第三方应用需打系统签名或修改源码包名白名单 2. Android 11+需在`/etc/permissions/privapp-permissions-platform.xml`声明权限 3. 重编译后需**清除data分区**确保权限初始化生效 4. 浮窗权限涉及屏幕叠加操作,需严格审核应用行为防止滥用[^3][^5]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

优快云资讯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值