10个最常见的Web安全漏洞

本文概述

  • 开始之前的一些网络安全入门–身份验证和授权
  • 常见的Web安全错误#1:注入漏洞
  • 常见Web安全错误2:身份验证失败
  • 常见Web安全错误#3:跨站点脚本(XSS)
  • 常见Web安全错误4:不安全的直接对象引用
  • 常见的Web安全性错误5:安全性配置错误
  • 常见的Web安全错误6:敏感的数据泄露
  • 常见Web安全错误7:缺少功能级别的访问控制
  • 常见Web安全错误8:跨站点请求伪造(CSRF)
  • 常见Web安全错误#9:使用具有已知漏洞的组件
  • 常见Web安全错误10:未经验证的重定向和转发
  • 结语
对于所有太多的公司而言, 直到发生安全漏洞后, 网络安全最佳做法才成为优先事项。在我作为IT安全专业人员的那几年里, 我一次又一次地看到如此众多的程序员对Web开发安全问题的世界感到多么晦涩难懂。
根据定义, 一种有效的解决网络安全威胁的方法必须是积极主动和防御性的。为此, 本文旨在激发安全意识, 希望为读者注入健康的偏执狂。
特别是, 本指南重点介绍了10个常见的重要Web安全陷阱, 包括有关如何缓解这些陷阱的建议。重点是由开放式Web应用程序安全性项目(OWASP)确定的十大Web漏洞, 这是一个国际性, 非营利性组织, 其目标是提高全球软件的安全性。
10个最常见的Web安全漏洞

文章图片
开始之前的一些网络安全入门–身份验证和授权 与其他程序员和IT专业人员交谈时, 我经常会遇到关于授权和身份验证之间区别的困惑。当然, 两者都经常使用缩写auth这一事实有助于加剧这种常见的混淆。这种混乱非常普遍, 以至于此问题可能应作为” 通用Web漏洞零” 包含在此帖子中。
因此, 在继续之前, 让我们澄清一下这两个术语之间的区别:
  • 身份验证:验证一个人是否是(或至少看起来是)特定用户, 因为他/她已正确提供了他们的安全凭证(密码, 安全问题的答案, 指纹扫描等)。
  • 授权:确认特定用户有权访问特定资源或被授予执行特定操作的权限。
换句话说, 认证就是知道一个实体是谁, 而授权就是一个给定的实体可以做什么。考虑到这一点, 让我们进入十大互联网安全问题。
常见的Web安全错误#1:注入漏洞 注入缺陷是由于经典的无法过滤不受信任的输入而导致的。当你将未经过滤的数据传递到SQL服务器(SQL注入), 浏览器(XSS –我们稍后将讨论), LDAP服务器(LDAP注入)或其他任何地方时, 都会发生这种情况。这里的问题是, 攻击者可以向这些实体注入命令, 从而导致数据丢失并劫持客户端的浏览器。
你的应用程序从不受信任的来源收到的所有内容都必须经过过滤, 最好根据白名单进行过滤。你几乎不应该使用黑名单, 因为正确设置黑名单非常困难, 而且通常很容易绕开。防病毒软件产品通常提供失败的黑名单的典型例子。模式匹配不起作用。
预防:好消息是, 防止注入只是简单地过滤输入并考虑输入是否值得信任的问题。但坏消息是, 除非可以毫无疑问地信任所有输入, 否则必须对所有输入进行适当的过滤(但在这里想到了” 永不言败” 的说法)。
例如, 在具有1, 000个输入的系统中, 仅对999个输入进行成功过滤是不够的, 因为这仍然留下一个字段, 可以用作解决系统崩溃的致命弱点。你可能会认为将SQL查询结果放入另一个查询中是个好主意, 因为数据库是可信任的, 但是如果外围不是可信任的, 则输入是间接地来自有恶意的人。如果你有兴趣, 这称为二阶SQL注入。
由于过滤非常难以正确执行(例如加密), 因此我通常建议你依靠框架的过滤功能:事实证明它们可以正常工作, 并且经过仔细检查。如果不使用框架, 则确实需要认真考虑是否在服务器安全性上下文中不使用框架是否真的有意义。 99%的时间没有。
常见Web安全错误2:身份验证失败 这是在身份验证失败时可能会出现的多个问题的集合, 但是它们并非完全出于同一根本原因。
假设有人仍然想在2014年推出自己的身份验证代码(你在想什么?), 我建议不要这样做。很难做到正确, 并且有很多可能的陷阱, 仅举几例:
  1. 该URL可能包含会话ID, 并在引荐标头中将其泄漏给其他人。
  2. 在存储或传输中, 密码可能未加密。
  3. 会话ID可能是可预测的, 因此获得访问权限并不重要。
  4. 会话固定是可能的。
  5. 可能会发生会话劫持, 超时未正确实施或使用HTTP(无SSL安全性)等问题的情况…
预防:避免此Web安全漏洞的最直接方法是使用框架。你可能能够正确实现此目的, 但是前者要容易得多。如果你确实想滚动自己的代码, 请非常偏执, 并让自己了解陷阱。有很多。
常见Web安全错误#3:跨站点脚本(XSS) 这是相当普遍的输入消毒失败(本质上是常见错误#1的特例)。攻击者在输入时向你的Web应用程序提供JavaScript标签。当此输入未经消毒返回给用户时, 用户的浏览器将执行该输入。它可以像制作链接并说服用户单击一样简单, 也可以更加险恶。在页面加载时, 脚本会运行, 例如, 该脚本可用于将Cookie发布给攻击者。
预防措施:有一个简单的网络安全解决方案:请勿将HTML标签返回给客户端。这具有抵御HTML注入的额外好处, 这是一种类似的攻击方式, 攻击者可以注入纯HTML内容(例如图像或大声的不可见Flash播放器)-不会产生很大的影响, 但肯定会令人讨厌(“ 请停止!” )。通常, 解决方法是简单地转换所有HTML实体, 以便< script> 作为< script> 返回。另一种常用的清除方法是使用正则表达式使用< 和> 上的正则表达式来剥离HTML标签, 但是这很危险, 因为许多浏览器会很好地解释严重损坏的HTML。最好将所有字符转换为逃脱的对应字符。
相关:9个基本系统安全面试问题
常见Web安全错误4:不安全的直接对象引用 这是信任用户输入并为由此产生的安全漏洞付出代价的经典案例。直接对象引用意味着内部对象(例如文件或数据库密钥)向用户公开。这样做的问题在于, 攻击者可以提供此引用, 并且, 如果未强制执行(或破坏了授权), 则攻击者可以访问或执行应避免的操作。
例如, 该代码具有一个download.php模块, 该模块读取并允许用户使用CGI参数指定文件名(例如, download.php?file = something.txt)来下载文件。不论是由于错误还是由于懒惰, 开发人员都忽略了代码的授权。攻击者现在可以使用它下载运行PHP的用户有权访问的任何系统文件, 例如应用程序代码本身或服务器上剩余的其他数据(例如备份)。哦哦
另一个常见的漏洞示例是密码重置功能, 该功能依赖于用户输入来确定我们要重置的密码。单击有效的URL后, 攻击者可以只修改URL中的用户名字段, 例如” admin” 。
顺便说一句, 这两个例子都是我本人经常在” 野外” 看到的东西。
预防措施:正确且一致地执行用户授权, 并将选择列入白名单。通常, 可以通过内部存储数据而不依赖于通过CGI参数从客户端传递数据来避免整个问题。大多数框架中的会话变量都非常适合此目的。
常见的Web安全性错误5:安全性配置错误 以我的经验, 配置错误的Web服务器和应用程序比配置正确的Web服务器和应用程序更为常见。也许这是因为不乏解决问题的方法。一些例子:
  1. 在生产环境中启用调试的情况下运行应用程序。
  2. 在服务器上启用目录列表, 这会泄漏有价值的信息。
  3. 运行过时的软件(例如WordPress插件, 旧的PhpMyAdmin)。
  4. 在机器上运行不必要的服务。
  5. 不更改默认密钥和密码。 (发生的方式比你想象的要频繁!)
  6. 向攻击者显示错误处理信息, 例如堆栈跟踪。
预防:拥有一个良好的(最好是自动化的)” 构建和部署” 流程, 该流程可以在部署时运行测试。可怜的人的安全性配置错误解决方案是提交后挂钩, 以防止代码使用默认密码和/或内置的开发工具发布。
常见的Web安全错误6:敏感的数据泄露 此Web安全漏洞与加密和资源保护有关。敏感数据应始终加密, 包括在传输过程中和静止时。没有例外。信用卡信息和用户密码永远不能传输或未加密存储, 并且密码应始终被散列。显然, 加密/哈希算法不能太弱-如有疑问, 网络安全标准建议使用AES(256位及以上)和RSA(2048位及以上)。
不用说, 会话ID和敏感数据不应在URL中传播, 敏感cookie应当具有安全标志, 但这非常重要, 不能过分强调。
预防:
  • 传输中:将HTTPS与正确的证书和PFS(完全转发保密)一起使用。不要通过非HTTPS连接接受任何内容。在cookie上有安全标记。
  • 在存储中:这比较困难。首先, 你需要降低曝光率。如果你不需要敏感数据, 请将其切碎。你没有的数据将不会被窃取。永远不要存储信用卡信息, 因为你可能不想与PCI兼容。使用诸如Stripe或Braintree之类的付款处理器进行注册。其次, 如果你确实需要敏感数据, 则将其加密存储并确保所有密码都经过哈希处理。对于散列, 建议使用bcrypt。如果你不使用bcrypt, 请对盐和彩虹表进行自我教育。
并且冒着明显的危险, 不要将加密密钥存储在受保护的数据旁边。这就像用带钥匙的锁来存放自行车。通过加密保护备份, 并保持密钥的私密性。当然, 不要丢钥匙!
常见Web安全错误7:缺少功能级别的访问控制 这仅仅是授权失败。这意味着在服务器上调用函数时, 未执行正确的授权。很多时候, 开发人员依赖于服务器端生成UI的事实, 他们认为客户端无法访问服务器未提供的功能。事情并非如此简单, 因为攻击者始终可以伪造对” 隐藏” 功能的请求, 并且不会因UI无法使此功能易于访问而受到阻止。假设有一个/ admin面板, 并且只有当用户实际上是管理员时, 该按钮才出现在UI中。万一缺少授权, 攻击者就无法发现该功能并滥用它。
预防措施:在服务器端, 必须始终进行授权。是的, 总是。任何异常或漏洞都不会导致严重的问题。
常见Web安全错误8:跨站点请求伪造(CSRF) 这是一个令人困惑的代理攻击的好例子, 浏览器被其他方欺骗以滥用其权限。例如, 第三方网站可能使用户的浏览器滥用其授权为攻击者做某事。
对于CSRF, 第三方网站使用你的浏览器和Cookie /会话向目标网站(例如你的银行)发出请求。例如, 如果你登录了银行主页上的一个标签, 并且容易受到攻击, 则另一个标签可能会使你的浏览器代表攻击者滥用其凭据, 从而导致混乱的代理问题。代理是滥用浏览器权限(会话cookie)来执行攻击者指示的操作的浏览器。
考虑以下示例:
攻击者爱丽丝(Alice)希望通过转移托德的一些钱来减轻托德的钱包的负担。托德的银行容易受到CSRF的攻击。要汇款, Todd必须访问以下URL:http://example.com/app/transferFunds?amount=1500& destinationAccount=4673243243打开此URL后, 会向Todd显示成功页面, 并完成转账。爱丽丝还知道, 托德经常访问自己所控制的blog.aliceisawesome.com网站, 并在其中放置以下代码段:< img src = http://www.srcmini.com/http://example.com/app/transferFunds?amount = 1500&destinationAccount = 4673243243 width = 0 height = 0 /> 当访问爱丽丝的网站时, 托德的浏览器认为爱丽丝链接到图像, 并自动发出HTTP GET请求以获取图片, 但这实际上指示托德的银行向爱丽丝转帐1500美元。
【10个最常见的Web安全漏洞】顺便说一句, 除了演示CSRF漏洞外, 此示例还演示了使用幂等HTTP GET请求更改服务器状态, 该请求本身就是一个严重漏洞。 HTTP GET请求必须是幂等(安全)的, 这意味着它们不能更改被访问的资源。永远不会使用幂等方法来更改服务器状态。
有趣的事实:CSRF也是人们过去用来填充饼干的方法, 直到会员变得更聪明为止。
预防措施:将秘密令牌存储在第3方站点无法访问的隐藏表格字段中。当然, 你始终必须验证此隐藏字段。有些网站在修改敏感设置时也会要求你输入密码(例如, 你的密码提醒电子邮件), 尽管我怀疑这样做是为了防止滥用你放弃的会话(例如, 在网吧中)。
常见Web安全错误#9:使用具有已知漏洞的组件 标题说明了一切。我再次将其归类为维护/部署问题。在合并新代码之前, 请进行一些研究, 可能还需要进行一些审计。使用代码, 你从GitHub上或一些论坛随机人有可能是非常方便的, 但也不是没有严重的网络安全漏洞的风险。
我曾见过许多实例, 例如, 站点是拥有站点的(即, 局外人获得对系统的管理访问权), 这不是因为程序员愚蠢, 而是因为第三方软件在生产中已经保持了多年未打补丁。例如, WordPress插件一直在发生这种情况。如果你认为他们找不到隐藏的phpmyadmin安装, 请允许我向你介绍dirbuster。
这里的教训是, 部署应用程序后软件开发不会结束。必须有有关如何维护和保持其更新的文档, 测试和计划, 尤其是如果它包含第三方或开源组件时。
预防:
  • 小心点。在使用此类组件时, 除了要格外小心, 不要成为复制粘贴编码器。仔细检查你将要放入软件中的代码段, 因为它可能无法修复而损坏(或者在某些情况下是故意恶意的-有时会无意中以这种方式邀请进行网络安全攻击)。
  • 保持最新。确保你使用的是你信任的所有内容的最新版本, 并计划定期进行更新。至少订阅有关该产品的新安全漏洞新闻。
常见Web安全错误10:未经验证的重定向和转发 这再次是输入过滤问题。假设目标站点具有一个redirect.php模块, 该模块将URL作为GET参数。操纵参数可以在targetsite.com上创建一个URL, 该URL将浏览器重定向到恶意软件install.com。当用户看到链接时, 他们将看到targetsite.com/blahblahblah, 该用户认为该链接是受信任的并且可以安全地单击。他们几乎不知道这实际上会将其转移到恶意软件删除(或任何其他恶意)页面上。或者, 攻击者可能会将浏览器重定向到targetsite.com/deleteprofile?confirm=1。
值得一提的是, 将未经消毒的用户定义输入填充到HTTP标头中可能会导致标头注入, 这是非常糟糕的。
预防:选项包括:
  • 完全不要进行重定向(很少必要)。
  • 具有要重定向到的有效位置的静态列表。
  • 将用户定义的参数列入白名单, 但这可能很棘手。
结语 我希望我能通过这篇文章使你的大脑发痒, 并引入健康的偏执狂意识和网站安全漏洞意识。
这里的核心结论是, 存在古老的软件实践是有原因的, 并且这种情况在过去适用于缓冲区溢出, 而今天仍然适用于Python中的腌制字符串。安全协议可帮助你编写(更多)正确的程序, 所有程序员都应该追求。
请负责任地使用此知识, 未经允许请勿测试页面!
有关更多信息和更特定的服务器端攻击, 请查看:https://www.owasp.org/index.php/Category:Attack。
欢迎欢迎你对此文章的反馈及其缓解建议。计划将来与之相关的职位, 尤其是有关分布式拒绝服务(DDoS)和老式(非Web)IT安全漏洞的问题。如果你对要编写什么样的网络保护有特定的要求, 请随时直接通过[电子邮件保护]与我联系。
这是网站安全!干杯。
有关:
  • JSON Web令牌教程:Laravel和AngularJS中的示例
  • 性能和效率:使用HTTP / 3

    推荐阅读