Android N 为什么强推 FileProvider?

2020-02-22 23:15:29 +08:00
 KunMinX

查了两天,整个网络都搜遍了,

官网的描述十分含糊,说是通过临时访问权限,提升安全性。抄来抄去的网文就更不用说了,只管是什么、怎么做,对为什么避而不谈。

那么问题来了,这个 “安全性” 究竟是对谁而言的?

appA 将内容分享给 appB,通过 FileProvider 究竟是为了保护 appA 旗下的内容,还是 appA 分享出去的这个内容本身,还是 防止 appA 借着这机会动态申请权限 而获得持久的外部存储访问权限 从而日后偷偷做坏事?

—— 它所谓的安全性,究竟主语是谁,究竟是在防什么???

就是对这个最根本的问题纠缠不清,先立个帖。有具体探究过的 v 友,还请不吝赐教!

7802 次点击
所在节点    Android
10 条回复
kzaemrio
2020-02-22 23:25:32 +08:00
大概比放开 sdcard 大家随便来强一些吧
winterbells
2020-02-22 23:31:11 +08:00
https://developer.android.com/reference/android/support/v4/content/FileProvider

In comparison, to control access to a file:/// Uri you have to modify the file system permissions of the underlying file. The permissions you provide become available to any app, and remain in effect until you change them. This level of access is fundamentally insecure.

应该是 AndroidX 了现在,不过都一样,就是原来 file 文件谁都能用,content 是给谁谁才能用(我是这么理解的)


记得有个 bug,带有浏览器功能的应用,只要打开 file://这种网页就能看到该应用内的所有数据文件(/data/data/xxx.)
KunMinX
2020-02-22 23:34:41 +08:00
@winterbells
感谢分享,例子 醍醐灌顶!

这两天我一直琢磨着 拍照调用和 apk 安装调用的场景,这下终于解释的通了。
crayygy
2020-02-22 23:39:50 +08:00
换个角度想,App A 要分享一个文件 F 给 App B,对于 A 来说,要么把这个文件写到一个外部路径,让 B 去获取( A 需要文件权限), 要么 A 把自己的内部文件权限给 B (基本上不可能也不安全)。在这种情况下,FileProvider 表示,你可以给一个只有 A 你自己能明白的路径给 B,并且只给 B 这一个路径的权限,这样 B 在读取的时候就可以安全的拿到且只能拿到这一个文件了。

所以说保护谁这个问题, 一方面保护了用户,不是每个需要分享功能的 app 都必须给文件权限, 另一方面保护了 A,因为它可以很方便的控制自己对外部暴露的内容,对于 B 而言,这种方式更像是一个黑盒,不需要关注对方有什么其他的东西,给我这个我就用这个。

个人拙见,希望有所帮助。
KunMinX
2020-02-22 23:57:45 +08:00
@crayygy 感谢。我复述一下自己的理解,

意思是说,appA 能访问自己内部存储私有目录的文件,是因为有这个权限 从 linux 层面修改私有文件的访问权限,而别的 app 没有,

而如果以 file uri 方式分享出去,等于同时将文件访问权限给暴露出去,因为 正因为我有这个权限,我才能访问和分享的,且分享时显然没能来得及将权限改回。于是其他 app 拿到 file uri,就可能基于权限访问到所属目录的其他内容。

而 FileProvider 提供了临时访问权限,使得事后能自动切回对外不可访问的权限。
RikkaW
2020-02-23 02:06:11 +08:00
小声一句,A 用 FileProvider 分享给 B,实际进行读写操作的是 A (
crayygy
2020-02-23 11:49:40 +08:00
@KunMinX #5
@RikkaW #6 的补充可以更好的理解这个问题,因为如果分享的是 file:// 的话,读写的是 B,A 丧失了主动权,无法控制权限范围和时效,但是用 FileProvider 的话,读写的是 A,A 对自己的内容拥有完整的控制权。
KunMinX
2020-02-24 12:32:13 +08:00
@crayygy 其实这么一说反倒迷惑了 😂 FileProvider 使用时,主要是给 file uri 转换成 content uri,就好像 web 开发中用虚拟目录来映射真实路径一样。除此之外,没有从源码中看到读写的痕迹,

并且,比如我要调用拍照程序,通过 FileProvider 不过是将 content uri 分享出去,那么外部拍照程序拍完照,总得通过 content uri,把内容通过 stream 给写进去吧,然后才轮到自己通过 stream 从中读。

所以 A 和 B 都有在读或写吧。
RikkaW
2020-02-24 14:38:28 +08:00
@KunMinX 看 FileProvider 里面的 openFile (
maokabc
2020-02-24 18:35:20 +08:00
A 一般是打开文件然后传递文件描述符给 B,实际读取在 B,还有就是通过管道转换,文件描述符一端给 B,这样两边都有读写

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/646703

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX