buuctf web_Web应用程序安全性:战斗自己或寻找理智的边缘

buuctf web

buuctf web

Web应用程序应有多安全? 好吧,对于我们许多Web开发人员来说,这个问题没有多大意义。 “应用程序必须尽可能地安全。 它越安全,就越好。” 但这不是一个确定的答案。 形成项目的安全策略无济于事。 此外,仅遵循该单一指令(“越安全越好”)可能被证明是一种不良服务。 为什么? 这就是我将在本文中讨论的内容。

安全性通常会使可用性变差

过多的安全检查无疑会使应用程序更烦人。 通常,对于应用程序的两个部分都是如此:身份验证和忘记密码功能。

除密码外,多阶段身份验证还包括SMS验证和其他保护字段,使用户体验更加安全,但乐趣更少。 如果您的所有服务都允许与其他用户交换有趣的图片,那么用户当然不会欣赏您尝试使自己的体验更加安全的尝试。

最佳安全做法建议在身份验证错误的情况下尽可能少显示信息,以防止入侵者收集用户列表。 根据此建议,如果用户经历了33个验证阶段并在一个字段中输入了错误,则最好的解决方案是显示以下消息:“对不起,出了点问题。 请再试一次”。 在这种情况下,用户不太可能会感受到对开发人员的感激和对他们为使用户体验尽可能安全所付出的努力的真诚钦佩。

您必须完全意识到,在这种情况下,用户体验会变得更糟,并确定在您的特定情况下这是否可以接受。

安全性使应用程序难以开发和支持

应用程序具有的防御机制越多,它的复杂性就越高。 创建应用程序某些部分所需的时间可能会增加几倍,以包括较小的安全性改进。

仅使入侵者的生活更令人沮丧,而不是解决实际的安全问题,就可以花费很多精力。 例如,项目可以选择在其REST API中混淆方法名称和参数名称。

通常,开发人员会花费大量时间来阻止入侵者通过登录表单,注册表单和忘记密码的表单获取用户名列表。

有一些方法,当应用程序将用户标记为入侵者,但不泄露它。 所有用户请求都将被忽略。

如果多阶段身份验证过程包含一个秘密问题,该问题对于每个用户来说都是唯一的,那么我们仍然可以为条目中不存在的用户名显示一个问题。 而且,应用程序可以在会话或数据库中存储此用户名和显示的问题,以始终要求相同的信息。

还有许多其他方法可以使入侵者感到困惑。 但是可以肯定的是,它们都需要时间来实施。 即使它的作者写得很好并且带有注释,这种逻辑即使对于它的作者来说也可能是错综复杂的。 但是最重​​要的是,它实际上并没有解决任何安全问题,只是阻止了发现此类问题。

将“精心设计且真正安全的功能”与“带有假想的黑客的狂野游戏”区分开来,并不总是那么容易。 尤其是因为这两个极端之间的优势不是绝对的,并且很大程度上取决于您的应用程序对潜在黑客有多大吸引力。

安全性使应用程序更难测试

我们所有的安全逻辑都必须经过测试。 单元测试,集成测试或手动测试–我们应该为我们拥有的每个安全机制选择一种合适的方法。

我们不能仅仅放弃测试我们的防御逻辑,因为错误往往会出现在我们的工作中。 即使我们一开始就能正确编写所有内容,也总是有机会在维护,支持和重构期间添加错误。 没有人通过编写遗留代码来启动项目。 该代码随着时间的流逝而成为传统。

彻底测试所有业务逻辑是不明智的,但是同时假设我们的安全机制是完美,绝对和无错误的。

如果将对安全逻辑进行手动测试,则存在一个问题,即必须多久完成一次。 如果我们的应用程序或多或少复杂,那么可能会有数十个(如果不是数百个)身份验证失败的地方。 例如,如果在某些请求中某些ID参数被更改,则服务器将返回我们不可访问的信息。 检查每种可能的情况都是一项繁重的工作。 在每个主要版本发布之前,我们都应该检查一下吗? 我们应该为此任务分配一个人吗? 还是我们应该为此组成整个团队?

这些问题很重要。 破碎的身份验证可以轻松地引入到项目中。 在对模型进行任何微小更改并添加新的REST方法时,我们必须保持警惕。 这个问题没有简单通用的答案。 但是有些方法可以在整个项目中始终如一地处理问题。 例如,我们在CUBA平台中使用角色访问组。 它们允许配置哪些实体可供哪些用户访问。 配置这些规则仍有一些工作,但是规则本身是统一且一致的。

除了身份验证损坏之外,还应该测试许多安全问题。 在实施新的机制或逻辑时,我们必须考虑如何对其进行测试。 未经测试的事物会随着时间的流逝而破裂。 而且,我们不仅在安全方面遇到问题,而且对一切都会好起来也抱有一种错误的信心。

造成最大麻烦的安全性机制有两种:仅在产品环境中起作用的机制和代表第二层(第三层,第四层)安全性的机制。

仅在生产上起作用的防御机制。 假设有一个会话令牌cookie,它必须有一个“安全”标志。 但是,如果我们在测试环境中到处使用HTTP,则意味着测试和生产有单独的配置。 因此,我们不完全测试将要发布的产品。 在迁移和各种更改期间,“安全”标志可能会丢失。 而且我们甚至都不会注意到。 我们如何处理这个问题? 我们是否应该引入另一个可以用作预生产的环境? 如果是这样,那么应该在此环境中测试我们功能的哪一部分?

多层防御机制。 有安全问题经验的人倾向于创建一个安全逻辑,只有在关闭其他安全机制后才能进行测试。 这实际上是有道理的。 即使入侵者设法在安全屏障的第一层中找到漏洞,他也将被困在第二层。 但是应该如何测试呢? 这种方法的典型示例是为应用程序的不同用户使用不同的数据库用户。 即使我们的REST API包含损坏的身份验证,黑客也将无法编辑或删除任何信息,因为db用户没有执行这些操作的权限。 但是,显然,如果维护和测试不当,此类配置往往会过时和破坏。

许多安全机制使我们的应用程序不太安全

我们拥有的防御检查越多,应用程序就越复杂。 应用程序越复杂,出错的可能性就越高。 出错的可能性越高,我们的应用程序的安全性就越差。

再次让我们考虑一个登录表单。 使用两个字段来实现登录表单非常简单:用户名和密码。 我们需要做的就是检查系统中是否有用户使用提供的名称,以及是否正确输入了密码。 好吧,也建议检查我们的应用程序没有显示在哪个字段中犯了错误,以防止入侵者获取用户名,尽管某些应用程序可以牺牲这种做法来获得更好的用户体验。 无论如何,我们还必须实施某种蛮力防御机制。 当然,该漏洞不应包含故障开放漏洞。 最好不要向入侵者透露我们知道他是入侵者,这也是一个好主意。 我们可以无视他的要求。 让他认为他正在继续入侵我们。 要检查的另一件事是,我们不记录用户密码。 好吧,实际上还有很多不那么重要的事情要考虑。 总而言之,标准的登录表单是小菜一碟,不是吗?

多阶段身份验证是完全不同的事情。 可以将某种令牌发送到电子邮件地址或通过SMS发送。 或者可以有几个步骤,涉及输入越来越多的信息。 这一切都是相当复杂的。 从理论上讲,这种方法应减少用户帐户被黑客入侵的可能性。 如果功能实现正确,那么情况就是如此。 仍然有可能被黑客入侵(也不会发送短信,电子邮件,也不会给我们100%的保证),但是通过这种方式,它会减少。 但是,已经很复杂的身份验证逻辑变得更加复杂。 而且犯错的可能性也会增加。 而且,与仅是一个具有2个字段的简单表格相比,单个错误的存在将证明我们的新模型不那么安全。

而且,侵入性和不便的安全措施可能迫使用户以较低的安全性来存储其敏感数据。 例如,如果在公司网络中需要每月更改一次密码,则不了解这种烦人措施的用户可能会开始在贴纸上写下密码并将其放在屏幕上。 “如果用户犯下这种愚蠢行为,这完全是用户的错”,您可以反对。 也许会。 但这绝对也是您的问题。 归根结底,我们作为开发人员的最终目标不是满足用户需求吗?

那你在暗示什么?

我建议从一开始就决定我们要走多远才能阻止入侵者。 我们是否准备好优化登录表单,以使登录请求的响应时间不会显示是否存在具有该名称的用户? 我们是否已经准备好实施如此可靠的检查,以至于即使是坐在手机旁的受害者的密友也无法访问应用程序? 为了使入侵者的生活更加痛苦,我们是否准备好使开发复杂化数倍,增加预算并牺牲良好的用户体验?

我们可以无休止地致力于安全性,建立新的保护层,改善监视和用户行为分析,阻碍信息获取。 但是,我们应该划清界限,将我们必须做的事情与我们不应做的事情区分开。 当然,在项目发展过程中,可以重新考虑和移动这条线。

在最坏的情况下,项目可能会花费大量资源来构建对一种类型攻击的强大防御,而在其他地方却存在巨大的安全漏洞。

在做出选择时,如果我们要实现某种安全性机制或要建立另一层安全性,则必须考虑许多事项:

  • 利用漏洞有多容易? 破坏的身份验证很容易被利用。 而且它不需要任何认真的技术背景。 因此,该问题很重要,应相应地加以处理。
  • 漏洞有多严重? 如果入侵者能够获取有关其他用户的敏感信息,或者更糟的是可以对其进行编辑,那么这将是一个非常严重的问题。 如果入侵者可以收集我们系统某些产品的ID,而不能将这些ID用于任何特别有趣的事情,那么问题就不那么严重了。
  • 如果我们实现此功能,应用程序将有多少安全性? 如果我们正在谈论额外的安全层(例如,检查输出中的XSS问题,或者已经实现了一种很好的输入清理机制),或者我们只是想让入侵者的生活更艰难(例如,尝试掩盖我们将他标记为黑客的事实),那么这些更改的优先级就不高。 也许它们可能根本没有实现。
  • 需要多少时间?
  • 它要花多少钱?
  • 用户体验会恶化多少?
  • 维护和测试功能有多困难? 常见的做法是从不尝试访问受限资源时就返回403代码,而总是要返回404代码。 这将使收集资源标识符变得更加困难。 尽管该解决方案使获取有关系统的信息更加困难,但同时使测试和生产错误分析变得复杂。 而且它甚至可能被证明对用户体验有害,因为尽管存在这种资源,但用户由于某种原因而变得不可访问,因此用户可能会收到一个混乱的消息,即没有这种资源,这甚至可以证明对用户体验有害。

好吧,可以肯定的是,在您的特定情况下,可能需要多阶段身份验证机制。 但是,您必须完全了解它以何种方式阻碍开发并降低用户对应用程序的兴趣。

您正在证明过失的安全措施

好吧,我不是。 当然,还有一些安全敏感的应用程序,这些应用程序将从其他安全措施中受益。 即使这些措施增加了费用并破坏了用户体验。

而且,当然,无论多么小,许多漏洞都不会出现在任何应用程序中。 CSRF是此类漏洞的典型示例。 防御它并不会使用户体验变差,也不会花费很多。 许多服务器端框架(例如Spring MVC)和前端框架(例如Angular)允许开箱即用地支持CSRF令牌。 此外,使用Spring MVC,我们可以快速添加任何必需的安全标头:Access-Control- *标头,Content-Security-Policy等。

不允许在我们的应用程序中使用残破的身份验证,XSS,SQL注入和其他一些漏洞。 对它们的防御很容易掌握,并且在各种书籍和文章中都有很好的解释。 我们还可以添加到此列表中,在URL参数内传递敏感信息,并存储弱散列密码和其他不良安全做法。

最好以最佳方式在项目中包含清单,该清单描述该项目的安全策略并回答以下问题:

  • 我们遵循哪些安全规范?
  • 我们的密码政策是什么?
  • 我们测试什么以及多久测试一次?
  • 等等

对于不同的项目,此宣言将有所不同。 如果程序在OS命令中插入了用户输入,则安全策略必须包含有关如何安全执行操作的说明。 如果项目可以将文件(例如头像)上传到服务器,则安全策略必须枚举可能的安全问题以及如何处理它们。

当然,创建和支持这样的宣言并非易事。 但是,期望团队中的每个成员(包括质量保证和支持)记住并坚持他必须执行的每种安全实践,这是一种幼稚的做法。 此外,存在一个问题,对于许多漏洞,有几种处理方法。 而且,如果对此事没有明确的政策,则可能发生在某些地方,开发人员使用一种做法(例如,他们验证输入信息),而在其他地方,他们做的事情完全不同(例如,对输出进行消毒)。 。 即使代码是好的和纯净的,它仍然是不一致的。 不一致是错误,支持问题和错误期望的理想之地。

对于具有恒定技术负责人的小命令,代码审查可能足以避免上述问题,即使没有宣言。

概要:

  • 在安全性方面,我们应该考虑我们的应用程序如何对安全性敏感。 银行应用程序和共享有趣故事的应用程序需要不同的方法。
  • 在安全性方面,我们应该考虑它对用户体验的危害。
  • 在安全性方面,我们应该考虑它将使代码复杂化并增加维护难度。
  • 安全机制应进行测试。
  • 建议教团队成员如何处理安全问题和/或对项目中的每次提交进行彻底的代码审查。
  • 每个应用程序都必须消除某些漏洞:XSS,XSRF,注入(包括SQL注入),破坏的身份验证等。

翻译自: https://www.javacodegeeks.com/2018/07/web-application-security.html

buuctf web

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值