今年,我们决定在 Jetpack Compose 中重写 Android 应用程序 ( github ),这也很有趣😃!我们很快就得到了一个实用的应用程序,并将其发送给公众审查。我们得到了很多反馈和贡献(我有没有提到这个社区摇滚?🤘💙)!
这是我们如何(以及为什么)公开我们的故事,google-services.json
以便任何人都可以轻松地做出贡献。
关于 google-services.json
每当您设置 Firebase 项目时,google-services.json
安装说明中都会很快出现。您通常从 Firebase 控制台下载它:
如果你打开它,你会发现类似这样的东西(一些值被编辑了,尽管我不是 100% 确定为什么,稍后会详细介绍):
{
"project_info": {
"project_number": "378302699578",
"project_id": "openfeedback-am-2022",
"storage_bucket": "openfeedback-am-2022.appspot.com"
},
"client": [
{
"client_info": {
"android_client_info": {
"package_name": "fr.androidmakers"
}
},
"api_key": [
{
"current_key": "[redacted]"
}
],
}
],
"configuration_version": "1"
}
如您所见,那里有东西被调用api_key
。这听起来很秘密,所以隐藏它当然是个好主意,对吧?嗯……事实证明这根本不是秘密。
您的 Android API 密钥不是秘密!
因为您的应用在运行时需要您的 API 密钥,所以 API 密钥必须可以在应用中的某个位置访问。所以真的不能保密。为了证明这一点,让我们尝试检索它。
首先在Google 上搜索 Android Makers 应用 apk。这会将您带到允许您下载 apk 的 ApkPure 网站:
单击并下载几个 MB 后,您可以在 Android Studio APK 分析器中打开该 APK(构建 -> 分析 APK...)。寻找看起来像 API 密钥的资源。这个google_api_key
字符串听起来是个不错的候选者🙃:
是的,放大一点......就是这样!所以我不确定为什么我在上面编辑它。当然,因为一切都是为了让你相信这应该被视为秘密。
可怕的警告
如果您曾经将这样的 API 密钥提交到 Github,所有存储库管理员都会收到一封电子邮件,内容如下:
好吧,这很可怕🙀...
如果您将应用程序发布到 Google Play,并在 Kotlin 代码中包含您的 API 密钥,情况也是如此:
这也太吓人了😱...
如果任何恶意用户可以在几分钟内检索到 API 密钥,为什么会出现所有这些警告?这对我来说仍然是个谜。我目前的猜测是没有办法区分客户端密钥和服务器密钥,因此警告会不加选择地发送给任何人。如果有人认为有充分的理由为 Android API 密钥显示这些警告,请告诉我,以便我可以编辑这篇文章并永久编辑所有内容😅(并使所有内容无效!)。
开放式发展
在浏览了一堆网络之后,意识到在 firebase 论坛中有一个官方答案(编辑:甚至在官方 Firebase 文档中,@zsmb13 让我后来意识到)并再次检查这些值是否在 apk 中,我们决定忽略可怕的警告,停止生活在恐惧中(🤘)并承诺google-services.json
!
现在任何人都可以使用真实数据为应用程序进行开发。特别感谢 @underwindfall
,@R4md4c
以及@oldergod
他们的出色贡献💙!
会出什么问题?
假设某人拥有您的 Android API 密钥。他们能用它做什么?
在我们的例子中,主要是使用我们的 Firestore 实例并使用我们的配额。我们可以想象有人开发自己的服务占用我们的 Firestore 实例,因此在月底不支付账单💸。
虽然在技术上是可行的,但我不确定这会有多实用。这样的服务将依赖于完全陌生的基础设施,任何更改都会几乎立即破坏它。我不知道已经发生过任何此类攻击,但也许这只是时间问题......
额外(实际)限制🔐
好消息是Google Cloud 控制台允许限制 API 密钥🎉
平台限制
您可以限制每个平台的 API 密钥:
在上面的示例中,我们将 API 密钥限制为只能从 Android 应用程序调用。正如@RickClephas 在 Twitter 上指出的那样,这通过使用两个 HTTP 标头来工作:X-Android-Package
和X-Android-Cert
. 所以它不是防弹的,但它仍然是一些东西。
API 限制
除了平台之外,您还可以将 API 密钥限制为某些 API:
[图片上传失败...(image-8dc2a-1660015159754)]
这确保不能使用其他 API,因此这是一个额外的安全性。确保包含Firebase Installations API
和Token Service API
/或您的应用程序将在几次通话后停止工作。
如果您的反馈在 Android Makers 期间没有被计算在内,这就是发生的事情 😅。感谢Hugo Gresse并@GerardPaligot
抓住了这个!
结论
您可以在 Github 中隐藏您的 Android API 密钥,但这不会阻止任何人获取它。如果您需要与同事或您的社区分享它,尽管有所有可怕的警告,但提交它应该是非常安全的。
归根结底,安全从来都不是“是”或“否”的问题,而是有更多的连续答案。有些人可能会争辩说,尽管存在所有缺陷,但从 GitHub 中隐藏您的 API 密钥仍然会使检索变得更加困难,这是非常正确的。确实,每项安全措施都有成本,无论是在原始美元方面还是在开发人员经验方面。
在所有可能性中:
- 添加GCP API 密钥限制
- 微调您的Firestore 安全规则
- 使用Firebase App Check 之类的工具检查您的应用完整性
- 用DexGuard 之类的东西混淆你的客户端代码
- 实施服务器端速率限制和欺诈检测
- 在 Github 中隐藏您的 API 密钥
我认为从 Github 隐藏你的 API 密钥是成本/安全比最差的。如果您依赖它来确保安全,您最好添加 API 密钥限制并仔细检查您的 Firestore 规则。
注意:当然,以上都不适用于服务器 API 密钥。如果您的 API 密钥最终没有出现在客户端中,请确保将它们安全地保存在您的基础设施深处。
链接:https://blog.mbonnin.net/about-the-android-makers-app-security-and-google-servicesjson
网友评论