Python 程序员如何试图扼杀我的所谓安全的 JavaScript API 服务
Python 程序员如何试图扼杀我的所谓安全的 JavaScript API 服务
一个开发者的噩梦

免责声明:在撰写本文期间,没有任何 Python 或 JavaScript 编码人员受到伤害。所有涉及编码员的行为都是安全模拟的,纯属虚构。
你有没有试过启动一个应用程序,却发现你的数字资产被你的 API 安全漏洞丢失了?你会想象像《精灵宝可梦 GO》一样广受欢迎,但又像《精灵宝可梦 GO》一样,担心你会失去对应用程序功能的控制,并且会激怒你的用户群?
2016 年 11 月,Fallible 的人创造了一个在线工具来逆向工程任何 android 应用程序以寻找秘密。在超过 16,000 个测试应用中,他们发现大约有 2500 个应用包含 API 密钥和/或秘密。这对安全不利。
代码冲浪
最近,为了提高我的 JavaScript 技能,我不想进行紧张的多日黑客马拉松,只是偶尔和其他程序员聚几个晚上。由此诞生了 JavaScript 代码冲浪 app。概念很简单;一个有着有趣项目和像样的 WiFi 的主机程序员会宣传一个聚会,其他程序员可以注册参加。主持人在他的项目上获得了一些关注,而与会者开始建立他们的 JavaScript 印章。这种商业模式完全是利他主义的,尽管我可以看到将这项服务充分货币化的方法,使其能够自给自足。
我先用 Node.js/Express,移动版构建了后端,最初推出了一个 Android 应用,iOS 紧随其后,我用一个简单的 RESTful API 将所有东西绑在一起。前端和后端实现都是完全开源的。
我使用了几个第三方 API 服务。例如,我使用了 GitHub API 来评估一个程序员的 JavaScript 声誉,基于他们的公共存储库活动和贡献。从一开始,我就用双因素授权实现了 OAuth2 用户授权。由于涉及到位置披露,我希望确保所有信息访问都得到适当的划分和保护。
溅射发射
在推出和一点社会推广之后,事情开始好转,这时候麻烦开始了。
第一个症状是 Android 应用程序完全无法收集 JavaScript 信誉分数。没有名声,没人能注册聚会。
我把问题追溯到 GitHub,所有的 API 调用都被完全限制了速率!我直接从 Android 调用 GitHub API,API id/密钥存储在我的应用程序中,我认为是安全的。然而,有人窃取了我的 GitHub 凭证,并在 API 中泛滥,完全封锁了我真正的 JavaScript 用户群。结果我的应用被嫉妒的 Python 程序员劫持了。
开源存储库中没有存储 API 密钥。密钥是直接从 Android APKs 中窃取的——我的应用程序没有通过易错测试。我尝试了代码混淆和对秘密进行编码,但这丝毫没有降低它们的速度。每次我更改密码都意味着整个安装基础的全面升级。这是一场失败的游戏。
难分难解的酣战
我的下一步是从 Android 应用程序中获取第三方 GitHub API 密钥。我没有直接从 Android 调用 GitHub API,而是扩展了自己的 API,通过自己的后端服务器代理调用 GitHub。至少我不再暴露 GitHub API 密钥了。
尽管朝着正确的方向迈出了一步,但这并没有让那些讨厌的蟒蛇慢下来多少。我的应用程序的 API 密钥是仍然隐藏在我的应用程序中的一个密钥,他们很容易就找到了。他们的回应是对我自己的 API 进行逆向工程,并使用它使我的后端服务器重复计算用户的 GitHub 信誉,像以前一样戏剧性地关闭了我的应用程序。
我用速率限制和在我的服务器上缓存用户信誉分数来应对。他们通过创建一群新用户,用虚假的 meetup 请求淹没我的服务来反击。
我被困在一个永无止境的捉迷藏游戏中,所有的虚假流量都让我在亚马逊网络服务上花费了真金白银。这是不可持续的。
不再有秘密
为什么我有一个 API 密钥?它应该是一个只有应用程序知道的秘密,这样只有应用程序才能成功调用我的 API,但在应用程序上保留这个秘密是有问题的。
我的用户认证是可靠的。事实上,我将它委托给了一个 OAuth2 授权服务,该服务返回一个用户授权令牌。我的应用程序从未见过任何用户凭证。
所以我使用了类似的方法来删除我的最后一个 API 秘密。这次,我将应用程序的身份验证委托给了一个应用程序身份验证服务。该服务对应用程序进行质询,并根据其响应证明该应用程序是可信的和未经篡改的。像用户认证服务一样,应用认证返回授权令牌。生成令牌的特殊秘密只有我的后端服务器和认证服务知道;它永远不会暴露在应用程序中,所以没有什么可偷的了。
证明应用程序的真实性很快,不需要人工输入,因此任何授权令牌的生命周期都可能很短。如果任何代币被盗,它的价值是有限的。
一旦我从应用程序中获得了最后一个秘密,我的服务就稳定了。试图重新打包我的 Android 应用程序或重放 API 调用都无法证明,我的成本又降了下来。
如果不是我又犯了一个错误,这个故事就到此为止了。在开发过程中,我生成了一个用于测试的长生命周期应用程序令牌,并将它放在了开源存储库中。这让皮托尼斯塔家族重操旧业。幸运的是,由于这个秘密已经不在应用程序中了,我干脆换了一个新的秘密。一旦更改了密码,危险的测试令牌就失效了,不需要对已安装的应用程序库进行更新。
经验教训
当我终于从噩梦中醒来时,我想到了可能会发生的事情。
我不得不花费大量的时间和金钱来抵御恶意攻击,而不是为我的应用添加功能和扩大我的用户社区。我不能在战斗中坚持太久。
你必须考虑到任何移动平台都是一个充满敌意的环境。这不仅仅是大多数开发者关注的用户真实性。还关乎 app 的真实性。使用第三方服务来证明您的应用程序提供了一种最佳实践方法来保持您的移动应用程序的安全。
永远不要低估程序员的毅力——JavaScript 和 Python 程序员都一样。
完全公开:我喜欢用 javascript、python 和其他语言编写代码,偶尔也会做梦;他们都有自己的快乐和挑战。我为 CriticalBlue 做软件性能和 API 安全方面的工作,而安全处理机密是我们业务的一部分。
感谢阅读!如果你能推荐这篇文章(点击❤按钮),让其他人也能找到,我将不胜感激。



