【问题标题】:What NOT to hard-code in an Android Application什么不能在 Android 应用程序中硬编码
【发布时间】:2019-06-22 18:37:04
【问题描述】:

我知道将带有凭据的数据库连接字符串、API-Key 等放入其中非常糟糕,因为您可以对其进行反编译以查看值...

那么所有东西都需要在 API 后面吗?

例如,实际上确实需要将什么放在 Web 服务后面:

是否需要将 SQL 查询放在 Web 服务之后,或者我们可以对存储过程进行参数化查询,这样可以吗?我假设这也需要在 Web 服务后面,并且只返回 JSON 数组之类的东西。

我还没有真正看到任何类型的清单,说明哪些内容不能放在移动应用的网络服务后面。

我来自网络开发的职位,所以直到现在这还不是问题。

我们基本上是否需要通过网络服务运行我们的应用程序,如果需要,我们如何着手将网络服务与应用程序结合起来,因为我们一开始无法硬编码网络服务的密钥地点?

总结:

我们是否需要创建一个包罗万象的网络服务,以便在数据库和安卓应用程序客户端之间进行交换,任何第三方 API 都一样?

此外,我们如何授权 android 应用与我们的网络服务交互,因为这个网络服务的目的首先是防止硬编码密钥?

【问题讨论】:

    标签: java android api security connection-string


    【解决方案1】:

    我知道将带有凭据的数据库连接字符串、API-Key 等放入其中非常糟糕,因为您可以对其进行反编译以查看值...

    是的,这在任何类型的应用中都非常糟糕,无论是移动、网络还是物联网应用。

    那么所有东西都需要在 API 后面吗?

    是的,您的应用需要尽可能地笨拙。换句话说,您的应用程序中的代码应该尽可能多地关注表示,任何业务逻辑都应该委托给 API 服务器。这种方法有一个巨大的优势,即每当您遇到错误时,您只需更新 API 服务器,而不是应用程序本身,并等待所有客户端在其移动设备中更新它们。对于 Web 应用,您不想向在浏览器中按 F12 并开始在开发人员工具面板中调试代码的任何人透露您的业务逻辑。

    是否需要将 SQL 查询放在 Web 服务后面,或者我们可以对存储过程进行参数化查询,这样可以吗?

    正如我之前所说,APP 必须尽可能地笨拙,并且永远不要从客户端向任何类型的后端执行 SQL 查询,否则您将在服务中打开一个巨大的安全漏洞。

    从客户端到您的后端的任何内容都必须被视为潜在恶意,因为即使您认为自己知道 正在发出请求,您也可能不知道 WHAT 成功了。为了更好地了解 WHOWHAT 访问您的服务器之间的区别,请阅读您这张图片所在部分的this article

    简而言之,WHO 表示用户,WHAT 表示执行请求的应用程序/设备,正如图片所示,它可能会被攻击者篡改中间人攻击。

    我假设这也需要在 Web 服务后面,并且只返回 JSON 数组等内容。

    Json 是从 API 返回响应最常用的格式,因为它易于人类和机器阅读,但也存在其他格式。

    我还没有真正看到任何类型的清单,说明哪些内容不能放在移动应用的网络服务后面。

    虽然您要求的列表可能不存在,因为它过于宽泛,但您可以先在移动应用中避免使用 OWASP Mobile Security Project - Top 10 risks

    我来自网络开发的职位,所以直到现在这还不是问题。

    虽然您可能没有在 Web 应用程序中使用 API 密钥,但如果您从它们执行 SQL 查询,那么您将面临 SQL 注入的风险,这是任何暴露于互联网的应用程序中最常见的风险,即继续在OWASP Top 10 - 2017(pdf) 上排名第一。

    我们是否需要通过网络服务来运行我们的应用程序

    是的,您需要通过 API 服务器运行您的移动应用程序。

    如果是这样,我们如何着手将 Web 服务与应用程序结合起来,因为我们一开始就无法硬编码 Web 服务的密钥?

    正如我在文章 How to Extract an API Key from a Mobile App by Static binary analysis 中所展示的,它可以借助几个开源工具来提取,例如使用 Mobile Security Framework,但您也可以通过中间人攻击来获取 API 密钥,正如我在文章Steal that API Key with a Man in the Middle Attack,使用了开源工具MiTM Proxy

    那么现在怎么办...如果我使用 API 密钥,它可以被提取,但如果我不使用,我无法识别 什么 正在发出请求。

    您现在可以采用多层防御,从 reCaptcha V3 开始,然后是 Web Application Firewall(WAF),最后如果您负担得起,则可以使用 User Behavior Analytics(UBA) 解决方案。

    谷歌reCAPTCHA V3

    reCAPTCHA 是一项免费服务,可保护您的网站免受垃圾邮件和滥用。 reCAPTCHA 使用高级风险分析引擎和自适应挑战来防止自动化软件参与您网站上的滥用活动。它在让您的有效用户轻松通过的同时做到这一点。

    ...帮助您检测网站上的滥用流量,而不会产生任何用户摩擦。它会根据与您的网站的互动返回一个分数,并让您更灵活地采取适当的行动。

    WAF - Web Application Firewall:

    Web 应用程序防火墙(或 WAF)过滤、监控和阻止进出 Web 应用程序的 HTTP 流量。 WAF 与常规防火墙的区别在于,WAF 能够过滤特定 Web 应用程序的内容,而常规防火墙充当服务器之间的安全门。通过检查 HTTP 流量,它可以防止源自 Web 应用程序安全漏洞的攻击,例如 SQL 注入、跨站点脚本 (XSS)、文件包含和安全错误配置。

    UBA - User Behavior Analytics:

    Gartner 定义的用户行为分析 (UBA) 是一个关于检测内部威胁、针对性攻击和金融欺诈的网络安全流程。 UBA 解决方案着眼于人类行为模式,然后应用算法和统计分析从这些模式中检测出有意义的异常——表明潜在威胁的异常。 UBA 不是跟踪设备或安全事件,而是跟踪系统的用户。 Apache Hadoop 等大数据平台通过分析 PB 级数据以检测内部威胁和高级持续性威胁,正在增加 UBA 功能。

    所有这些解决方案都基于否定识别模型,换句话说,它们会尽力通过识别什么是坏的而不是什么来区分好与坏,因此它们很容易出现误报,尽管其中一些人使用的先进技术,例如机器学习和人工智能。

    因此,您可能会发现自己经常不得不放松阻止对 API 服务器的访问的方式,以免影响好用户。这也意味着此解决方案需要持续监控,以验证误报不会阻止您的合法用户,同时它们是否正确阻止了未经授权的用户。

    对于服务于移动应用的 API,可以通过使用移动应用证明解决方案来使用积极的识别模型,该解决方案向 API 服务器保证请求可以被信任,而不会出现误报。

    移动应用证明

    使用移动应用证明解决方案让 API 服务器知道只接收来自正版移动应用的请求。

    移动应用证明服务的作用是在运行时通过在后台运行 SDK 来保证您的移动应用没有被篡改或没有在有根设备中运行,该 SDK 将与在云中运行的服务进行通信以证明移动应用程序和正在运行的设备的完整性。

    成功证明移动应用程序的完整性后,会发出一个短期 JWT 令牌,并使用只有云中的 API 服务器和移动应用程序证明服务知道的秘密进行签名。如果移动应用证明失败,JWT 令牌会使用 API 服务器不知道的秘密进行签名。

    现在,应用程序必须在每个 API 调用中发送请求标头中的 JWT 令牌。这将允许 API 服务器仅在可以验证 JWT 令牌中的签名和过期时间时服务请求,并在验证失败时拒绝它们。

    一旦移动应用程序不知道移动应用程序证明服务使用的秘密,即使应用程序被篡改、在有根设备中运行或通过正在成为中间人攻击的目标。

    Mobile App Attestation 服务已经作为 Approov(我在这里工作)的 SAAS 解决方案存在,它为多个平台提供 SDK,包括 iOS、Android、React Native 等。集成还需要对 API 服务器代码进行小检查,以验证云服务发布的 JWT 令牌。此检查对于 API 服务器能够决定服务哪些请求和拒绝哪些请求是必要的。

    回复您的总结

    我们是否需要创建一个包罗万象的网络服务,以便在数据库和安卓应用客户端之间进行交换,对于任何 3rd 方 API 都一样?

    是的,您应该始终在任何类型的应用程序、移动设备、Web 或 IOT 应用程序中委托对第三方服务的访问,否则当攻击者获取访问凭据并开始在您的设备上使用它们时,您将遇到麻烦代表,而您将是支付账单的人。

    另外,我们如何授权 android 应用与我们的网络服务交互,因为这个网络服务的目的首先是防止硬编码密钥?

    移动应用证明解决方案看起来最适合这里。

    结论

    在客户端运行并且需要一些秘密来访问 API 的任何东西都可能以不同的方式被滥用,您必须将所有第三方 API 的访问权限委托给您控制的后端,以减少攻击面,同时保护他们的秘密不被公众窥探。

    最后,为保护您的 API 服务器而使用的解决方案必须根据您要保护的内容的价值以及该类型数据的法律要求(例如欧洲的 GDPR 法规)来选择。

    【讨论】:

      【解决方案2】:

      通常您会创建一个后端服务,该服务会公开一些 API 供您的应用使用

      EG 您可以在 myserver.com/something 上拥有一个 API,这将是一个 PHP 脚本或其他一些服务器端语言。这将返回应用程序需要显示的数据。您使用 JSON 之类的东西对数据进行编码,应用程序可以使用合适的库来读取它。

      发送数据的工作方式类似,创建一个可以通过 HTTP 接受 POST 请求并将数据存储回数据库的 API。登录名和 SQL 都应该在服务器端。

      例如应用程序使用参数 someInfo="hello world" 向 server.com/storeInformation 发送请求

      服务器端(例如 php)然后执行查询 INSERT INTO myTable VALUES (...whatever..)

      关键是客户端应用程序永远不需要直接发送 SQL(因为这是不可信的),而是应该发送它想要完成的内容,并由服务器决定如何完成。

      作为一项规则,请记住,客户永远不能被信任。任何人都可以使用任何参数调用您的服务器 API。

      【讨论】:

      • 但是如何确保只有我的应用可以使用我的网络服务?
      • @Sanguine 你不能。您需要考虑到这一点来构建所有内容。这就是为什么你不能让前端应用程序发送 SQL 命令的原因,因为你不知道只有你的应用程序在发送它们。请告诉我们您要达到的目标
      • 想象一下使用用户帐户登录。我只希望某些用户能够访问数据库中的某些数据位。每次他们想要检索某些东西时,我是否必须发送他们的登录详细信息以进行身份​​验证?
      • @Sanguine 是的。对于初学者,您可以这样做,记住应用程序端的密码和用户名,然后在每次请求时再次发送它们(将来您应该研究比存储密码更好的技术)。请记住:服务器上的每个请求都必须被视为可能来自恶意人员
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-28
      • 2014-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-02
      • 1970-01-01
      相关资源
      最近更新 更多