网络热传App鉴定 |「得物」疑私删用户视频?从技术角度还原事件始末

news2024/10/6 22:20:38

声明:本文更注重于原理知识的普及,因此文中不会有大量实际代码的展示,如果想从代码层面上了解「应用存储分区」的内容,欢迎阅读我两年前写过的技术文章《Android 10 应用分区存储适配实践》


近日,有网友爆料,称其发现得物App有疑似偷偷调用手机权限删除用户视频的行为。

事件的起因,是该网友在得物App上购买到的商品有问题,于是按流程向平台方反馈,并上传了相关的视频证据。

但没过多久,其手机上就收到了一条系统推送提醒,内容是检测到“得物”删除了视频,已成功拦截,据该网友推测,被删除的正是作为重要维权证据的那条视频。

此事一经曝光,立即在网上掀起了轩然大波。从大量评论跟进的内容上看,网友们最关注的问题集中在:

得物App到底有没有未经用户同意,就删除了用户手机相册中的视频?

随着事情的逐渐发酵,得物App也紧急连发了两条声明,最新的一条声明回应称:删除的是编辑、处理、上传过程中产生的临时缓存文件,是对该临时缓存文件的处理触发了系统拦截通知

声明发出后,有相当一部分网友采纳了这个说法,毕竟类似的误报之前也已经在其他App上发生过不少了。到这里,事情似乎告一段落了。

但是,这真的可以简单归结为系统拦截通知的误报吗?多年从事Android开发的直觉告诉我,这件事情的背后,肯定还有更加深层的原因。

也是基于这种直觉的驱使,经过了大半个晚上的信息收集、情景模拟以及测试验证,我大致上已经能够梳理出这整件事情的来龙去脉了。

先抛出结论,这其实是一场由「Android系统的历史遗留问题」,「得物App对于适配工作的不作为」以及「系统拦截App删除操作的判定规则」三者共同作用下所引发的「乌龙事件」

故事,还得先从Android系统的历史遗留问题开始讲起。

Android系统的历史遗留问题

Android 10之前:乱象丛生

在Android 10之前,Android系统对于App的文件存储,既没有强硬的存储规范,也没有可参考的存储建议

在此混沌的背景下,只要能申请到必要的文件读写权限,每一个App就都可以在手机存储空间的任意位置建立属于自己的目录,访问系统目录或其他App的目录也是完全没有任何限制。

打开你手机上的「文件管理器」,你认得出以上是哪几个App建立的目录吗?

这样做直接导致的结果就是,用户根本无法区分和管理不同App的文件,一打开文件管理器,能看到的除了混乱无序,还是混乱无序。

Android 10:应用分区存储开始实施

也许是Android系统也意识到了这个问题的严重性,所以在Android 10之后大刀阔斧地引入了应用分区存储的概念,也即为每个App划分了一个专有目录,默认情况下,App只能访问这个专有目录下的文件。

如果App尝试访问此目录之外的文件,就会发生错误,即使已经申请了文件读取(READ_EXTERNAL_STORAGE)权限

而如果App需要访问公有目录(比如系统相册)下的照片、视频、音频等媒体文件,则需要使用另外的MediaStore API来访问。但是对于这个API的使用,Android系统也同样收紧了权限。

比如现在你想要删除公有目录下的某个媒体文件,系统就会向你抛出一个RecoverableSecurityException异常,中断你的删除行为,以告知你正在进行危险的操作,为此你需要再次请求弹出一个系统级的弹窗,告知用户你正在进行删除操作(弹窗上的文字描述不可自定义),在征求用户的同意之后方能删除媒体文件。

立意虽然是好的,但是这个巨大的行为变更,相当于要求App把之前经过数个版本甚至数十个版本才建立的文件目录结构完全推翻,不仅要把之前可能分散各处的文件重新聚拢到App专有目录下,还要成片成片地修改之前的代码实现。如果短期内强硬要求执行,那必然将是怨声载道,哀鸿遍野。

所以,针对那些短期内无法完成迁移工作的App,Android系统又给留了一个后门。开发者们可以通过添加requestLegacyExternalStorage清单属性,允许App适配Android 10的其他变更,但暂时停用分区存储

表现出来的样子就是App可以沿用之前文件目录结构,暂时不需要做任何改变。

Android 11:强制执行分区存储

但当将App更新到以Android 11为目标平台后,Android系统会忽略该属性,即会强制执行分区存储

意思很明确:机会呢,我是给过你了,都过了一个版本了你还不改,那就等着App崩溃吧你。

所以呢,只要是以Android 11为目标平台的App,基本上都是已经完成了应用分区存储的适配,现在它能自由操作的,只能自身专有目录下的文件。而对于公有目录下的媒体文件,基本上就只有查看的权力,如果需要修改或者删除,则如上面所说,需要用户授权才能操作,而不能再像之前那样无感知修改和删除了。

得物App对于系统适配工作的不作为

那好,现在由你来猜一下,本轮事件中的当事App「得物」可能处于以上描述的哪一个阶段?

3…2…1!

保留好你的答案,下面我们先用排除法来排除明显错误的选项。

得物App在发布的第二条声明里,还附上了其App发布动态时的文件缓存管理方案示意图,如下:

我们主要关注其步骤2——「复制到临时目录」,这里我们可以看到,得物App是将原视频复制了一份到/pictures/duapp/a.mp4路径下,也就是在文件管理器的Pictures目录下创建了一个名为duapp的临时目录。

Pictures目录是干什么用的?这个目录是用于放置用户可用图片的,属于外部存储公有目录下的预定义子目录之一。

既然得物App可以自由复制文件到公有目录,那么就可以排除第3个选项了,也即得物App并没有以Android 11为目标平台

剩下2个选项我们也不欲盖弥彰了,直接下载本轮事件曝光之前,得物App最后一个版本的安装包文件(*.apk)一探究竟即可。

从解压缩后的安装包的AndroidManifest.xml清单文件中我们可以看到,该版本的得物App所适配的目标SDK版本为29,也即Android 10,并且添加了requestLegacyExternalStorage属性,也即请求暂时停用分区存储。

所以,正确答案是第2个选项,得物App并没有适配Android 10的应用分区存储变更

话说,连Google Play都要求上传的App必须适配Android 12了,Android 13也都已经出Beta版了,得物App你这样一直苟在Android 10里真的没问题吗?

系统拦截App删除操作的判定规则

最后,我们还有一个问题没有弄明白,也即:

得物App删除了其放置在公有目录下的临时缓存文件,系统在这个时候拦截了此行为,真的是属于误判吗?

为了还原系统拦截行为的一个合理性,我们需要先理清系统拦截App删除操作的判定规则,为此,我们设立了3个对照组,均以Android 10为目标平台

建立对照组

  • 实验组:添加了requestLegacyExternalStorage属性,即暂时停用分区存储,直接删除公有目录下的媒体文件

  • 对照组1:不添加requestLegacyExternalStorage属性,即必须得到用户的授权之后才能删除公有目录下的媒体文件

  • 对照组2:不添加requestLegacyExternalStorage属性,只删除其应用专有目录下的媒体文件

用于验证的示例项目,来源于Android开发者官网提供的MediaStore示例,该示例原本的设计是用于演示如何使用MediaStore API来正确显示手机相册中的图片的。

演示的手机选用是Huawei P30 pro,该型号能稳定重现系统拦截操作的推送通知。

结果展示

实验组:固定收到了系统拦截App删除操作的推送提醒。

对照组1:获得用户授权之后能正常删除照片,没有收到系统拦截App删除操作的推送提醒。

对照组2:既不需要授权,也没有收到系统拦截App删除操作的推送提醒。

通过这个对照结果,我们很容易能倒推出系统拦截App删除操作的判定规则:

  1. 系统认为,对于公有目录下的媒体文件,App只应保有读取的权限,修改、删除该媒体文件都属于越权行为,是有可能侵害到用户重要的个人资产的。

  2. 确实有需要删除某个公有目录下的媒体文件的,App必须尽到告知用户的义务,并把删除的选择权交给用户,在得到用户授权之后才可以删除。

  3. 如果App只是修改、删除其专有目录下的媒体文件,系统会认为这是App内部对其缓存文件正常的维护行为,故而不会干涉这类操作。

到这里,我们可以总结一下,这场乌龙事件之所以会发生,根本问题在于,旧系统的遗留问题与新系统的保护措施起了冲突

得物App使用了不合理的文件缓存管理方案——将临时缓存文件保存到了公有目录下。因此命中到了系统拦截App删除操作的判定规则,进而收到了相关的系统推送提醒。

要真正解决这个问题,需要得物App积极推进对Android 10应用分区存储的适配,将对文件缓存管理迁移到App专有目录下进行,就不会引致此类事件的发生。

——这就是得物App疑偷删用户视频整件事情的始末。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/14115.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL 分库分表

MySQL分库分表 概念 读写分离优化了互联网读多写少场景下的性能问题,考虑一个业务场景,如果读库的数据规模非常大,除了增加多个从库之外,还有其他的手段吗?实现数据库高可用,还有另外一个撒手锏&#xff…

Python性能优化指南--让你的Python代码快x3倍的秘诀

Python性能优化指南 Python最为人诟病的就是其执行速度。如何让Python程序跑得更快一直是Python核心团队和社区努力的方向。作为Python开发者,我们同样可以采用某些原则和技巧,写出性能更好的Python代码。本文将带大家深入探讨Python程序性能优化方法。…

99页4万字XX大数据湖项目建设方案

目 录 1. 项目综述 1.1. 项目背景 1.2. 项目目标 1.3. 项目建设路线 2 需求分析 2.1功能需求 2.1.1 统一数据接入 2.1.2 数据迁移 2.1.3 数据范围与ETL 2.1.4 报表平台 2.1.5 安全管理 2.1.6 数据治理 2.2非功能需求 2.2.1运维保障需求 2.2.2可用性需求 2.2.3可…

MQTT 具备那些特征?

目录 1、MQTT 中的 QoS(消息服务质量) (1)为什么服务质量(QoS)很重要? (2)QoS 在 MQTT 中是如何工作的? (3)如何选择正确的 QoS 级别 (4&a…

Java开发中Word转PDF文件5种方案横向评测

Java开发中Word转PDF文件5种方案横向评测 前段时间接了个项目,需要各种处理Word模板、转PDF、签章等等,非常头疼,其中光是一个word转PDF就折磨我好久,实现转换很简单,但是效果总是达不到满意,于是我把市面…

【Linux】关于普通用户无法使用sudo指令的解决方案

文章目录前言解决方案结语前言 在这篇博客中,测试 rm -rf 删除文件时无视权限暴力删除的效果时,使用了 sudo 指令。 但是sudo指令是不能直接使用的,需要修改一些设置。 当时我遇到这个问题时,困惑了许久,查找解决方…

JVM执行引擎

文章目录学习资料执行引擎概述工作过程Java代码编译和执行的过程什么是解释器(Interpreter),什么是JIT编译器?为什么说Java是半编译半解释型语言?机器码、指令、汇编语言、高级语言机器码指令指令集汇编语言高级语言字…

UE5实现PS图层样式投影效果

一、PS图层样式投影效果 1、创建材质函数 MF_PS_Style_Shadow 公开到库(可选) 定义 function input。 Shadow代码: /** PS图层样式投影效果param {UVs} texture coordinateparam {TextureObject} texture objectparam {TextureSize} …

十、children的深入用法-React.Children对象上的方法

目标 理解什么是children掌握React.Children对象上的方法 知识点 什么是children上图中我们看到了,我们之前学过的React.createElement方法,现在大家发现jsx的内容,全部都体现在了该方法上;那么React.createElement其实是有三个…

专精特新企业数据集两份数据

专精特新企业数据集 一、三批专精特新上市、非上市公司数据分布 1、时间截止至2021年8月 2、区域范围:上市和非上市公司两大板块,涵盖申万一级行业 3、指标说明: 包含如下内容:专精特新上市公司名单汇总、第一批专精特新上市公…

opencv 入门学习

opencv 演示 输入说明 原图在顶层后然后再去按键,不然会失效(未知原因) 1.roberts 边缘检测 2.sobel算子 3.Canny算子 4.Laplace算子 5.Canny算子,轮廓显示 空格 人脸检测准备一张图片效果 默认显示原图和灰阶图 roberts 边缘…

MySQL版本号6和7去哪了

问题 MySQL版本号6和7去哪了 详细问题 笔者起初误以为MySQL版本号6和7可能由于存在诟病不受欢迎或由于MySQL版本迭代过快导致未能在市场上流行 但是在浏览MySQL官网注意到 MySQL在2017年发布了新的版本8.0,但是在此之前的上一一个版本是5.7,40,那么中间的6和7去哪…

并发编程永远绕不开的难题,跟着大牛带你Java并发编程从入门到精通

我们知道,很多框架或者自研组件的底层,都或多或少涉及到并发编程方面的技术点。 比如:在一些本地缓存组件中,当本地缓存过期后,需要从数据库加载数据,这个阶段中就会涉及到线程并发请求的处理;在…

微信小程序云开发

概念 小程序云开发,让前端程序员拥有后端的能力云函数 (nodejs)云数据库 (mogodb)云存储前端写好云函数 > 上传到云服务器 >实现自定云部署前端去调用云函数>间接通过云函数对数据库的操作前端>全栈 注意…

DSP之寄存器映射和CDM文件

DSP之寄存器映射和CDM文件 RAM:程序运行速度快,关掉电源,程序会丢失。 Flash:程序运行速度慢,关掉电源,程序不会丢失。 所以,程序一般存到Flash中,在运行的时候,由CPU将…

2010-2019年208个地级市城乡收入差距泰尔指数

2010-2019年208个地级市城乡收入差距泰尔指数 1、数据来源:各省的统计NJ以及部分地级市的NJ(主要是地级市的城镇化率) 城镇化率为常驻人口城镇化率而非户籍人口城镇化率。附件中也包含各个地级市的城镇化率,农村人均可支配收入2…

Linux开发工具(1)——yum

文章目录软件包管理器 —— yum安装软件的三个问题Linux开源生态yum查找软件yum下载软件yum删除软件配置yum源Linux下的工具本质也是指令 , 下面我会介绍几个常用的工具 , 分别是yum(相当于是手机上的应用商店 , 可以在里面下载工具 ) vim(多模式编辑器)…

【毕业设计】深度学习行人车辆流量计数系统 - 目标检测 python

文章目录0 前言1. 目标检测概况1.1 什么是目标检测?1.2 发展阶段2. 行人检测2.1 行人检测简介2.2 行人检测技术难点2.3 行人检测实现效果2.4 关键代码-训练过程3 最后0 前言 🔥 Hi,大家好,这里是丹成学长的毕设系列文章&#xff…

机器学习-SVM算法

文章目录支持向量机1. 间隔与支持向量1.1. 点到超平面的距离1.2. 去掉绝对值1.3. 最大间隔2. 对偶问题2.1. 引入拉格朗日乘子2.2. 求偏导2.3. 得到对偶问题2.4. 求解内层函数 minw,bL(w,b,α)min_{w,b} L(w,b,\alpha)minw,b​L(w,b,α)2.5. 求解外层函数 maxαminw,bL(w,b,α)m…

.ko 加载报错 “unknown symbol in module or invalid parameter” 排查解决方法

.ko 加载报错 “unknown symbol in module or invalid parameter” 排查解决方法 问题来源 今天参照Sigmastar的文档,修改config重新编译kernel,打开板上RNDIS虚拟网口。 按照步骤重编后,在demo.sh加入insmod指令,按顺序在启动…