Web 应用程序中的数据流

博客探讨了Web应用程序安全的挑战,尤其是SQL注入和跨站脚本攻击。由于Web应用由多个互不信任的组件组成,每个组件都需要处理潜在的恶意输入,使得数据清理变得复杂。文章通过图论分析了数据路径,指出每次数据发送到数据库时都需先清理。解决方案包括使用安全接口和清理库,以减少开发者的安全负担。
摘要由CSDN通过智能技术生成

Web Application Security - Defuse Security

当然,如果您最近一直在关注新闻,您会看到很多关于网站被黑客入侵以及其数据库被泄露的报道。网站违规显然变得越来越普遍,但为什么呢?

看起来 Web 应用程序应该比桌面应用程序更安全。它们通常是用托管语言编写的,因此开发人员不必担心低级缓冲区溢出样式的漏洞利用。那么,是什么让构建安全的 Web 应用程序如此困难?

Web 应用程序有自己独特的一组漏洞利用。最常见的:SQL Injection 和 Cross Site Scripting 已经很好理解了,我就不解释了。我要解释的是,为什么它们如此难以预防。

一般的 Web 应用程序由四个互不信任的组件组成:

  1. 网络浏览器(用户输入)
  2. 外部代码(库)
  3. 数据库(及其内容)
  4. 生成 Web 浏览器请求的页面的脚本

这些组件中的每一个都必须接受来自另一个组件的潜在危险输入,如下图所示:

每个红色箭头提示来自其他组件之一的潜在危险输入。外部代码库不能假定页面生成脚本传递给它的所有内容都已正确清理。同样,页面生成脚本不能假设外部代码返回的数据将被正确清理。外部代码和页面生成脚本都不能假设存储在数据库中的数据已经过清理。

数据库和网络浏览器是愚蠢的,从某种意义上说,它们总是按照指示去做,并且无法区分好输入和坏输入。因此,必须对发送到数据库或 Web 浏览器的任何数据进行清理,否则就有可能被利用。

要分析 SQL 注入攻击的可能性,请查看图表。跟踪来自网络浏览器的数据到达数据库的所有可能路径。现在我们可以看到为什么 Web 应用程序如此难以保护:危险数据可以通过多种路径到达数据库。如果这些路径中只有一个将数据传递到数据库而不对其进行清理,则该网站很容易受到 SQL 注入攻击。

例如,数据可以遵循以下任何路径:

Web 浏览器 --> script.php --> 数据库
Web 浏览器 --> script.php --> 外部代码 --> 数据库
Web 浏览器 --> script.php --> 数据库 --> script.php --> 数据库
Web 浏览器 --> script.php --> 数据库 --> 外部代码 --> 数据库
等等....

在图论中,这些实际上被称为游走,它们的数量是无限的。

您可能已经注意到 script.php 始终是路径中的第二步。如果 script.php 清理了所有 Web 浏览器的输入不是很好吗?这将是美妙的,但它不能。因为在针对特定平台对数据进行了清理之后,除该平台之外的任何其他人都无法理解它。

为了证明我的观点,假设我们正在构建一个带有一些数据库软件的网站,如果字符串“21”出现在查询中的任何位置(通过自毁,我的意思是服务器实际上 EXPLODES),则该软件会自毁。现在想象我们正在构建一个地址簿网站。

假设 Web 浏览器要求我们的脚本将地址添加到数据库中,并发送以下信息:

  • 国家:美利坚合众国
  • 州:加利福尼亚
  • 城市:比佛利山庄
  • 地址:第 31 街 6556 号
  • 邮编:90210

你可以看到这里有一个潜在的问题。如果我们直接将这些数据插入数据库,邮编中的“21”会导致数据库爆炸。我们不希望我们的数据库爆炸,所以我们定义了我们的清理函数,将“21”替换为“TWENTYONE”。我们的数据库软件知道“21”问题,所以当它被要求存储值“TWENTYONE”时,它很聪明地首先将它转换回“21”(不会爆炸)。

如果 script.php 清理数据,它将变为:

  • 国家:美利坚合众国
  • 州:加利福尼亚
  • 城市:比佛利山庄
  • 地址:第 31 街 6556 号
  • 邮编:90T-WENTYON-E10

现在,script.php 可以安全地将其添加到数据库中。但是如果 script.php 想要使用外部代码库来检查邮政编码是否实际上是该州的有效邮政编码怎么办?不能,因为数据已经过清理。外部库不知道“90T-WENTYON-E10”是什么意思。不幸但不可避免的是,传递给外部库的任何数据 script.php 都必须未经处理。

如果外部库需要在数据库中查找邮政编码,或者script.php从数据库中拉出一个邮政编码并重新插入,或者如果script.php从外部库中获取了一些信息并想要插入,该怎么办?它进入数据库?在所有这些情况下,Web 应用程序的程序员必须注意在将数据发送到数据库之前对其进行清理。

换句话说,每次将数据发送到数据库时,都必须首先对其进行清理。如果 Web 应用程序中有 1000 个位置将数据发送到数据库,则需要进行 1000 次数据清理。如果仅缺少一个,则可能发生 SQL 注入攻击。

这同样适用于跨站点脚本攻击。跟踪数据可能从 Web 浏览器、通过网站并返回浏览器的所有路径。

不全是坏消息

使用我们基于图论的对 Web 应用程序安全性的理解,我们可以发现更有效的方法来保护网站。

通过查看图表,我们看到实际上只有两个数据库输入路径和一个 Web 浏览器输入路径。在大多数网站中,数据库清理将在“外部代码”和“script.php”中完成,而 HTML 清理将在 script.php 中完成。以这种方式完成后,图中的每个输入路径都代表了查询数据库或将数据发送到浏览器的所有 1000 行代码。这对 script.php 和外部库的开发者来说是一个巨大的负担;它迫使他们不断地寻找发送到数据库或浏览器的未经处理的数据。他们必须是安全专家。

我们可以通过添加“第四方”清理库来解决这些问题,这些库定义了数据库和 Web 浏览器的“包装器”接口。它看起来像这样:

在此设置中,接口 A 和 B 由安全专业人员开发,旨在为客户端代码提供相同(或更多)的功能,就好像它们不存在一样。“外部代码”和“script.php”的开发者从不直接与数据库或浏览器打交道;他们总是通过安全界面。因为他们使用接口,所以他们不必担心 SQL 注入和跨站点脚本等经典漏洞。

它不会阻止他们通过应用程序级逻辑错误(如文件上传、包含、exec() 或正则表达式)引入安全漏洞。但是这种方法是一个巨大的改进;接口 A 和 B 只需要编写一次,并且可以在整个应用程序中重复使用。

接口 A 允许数据库在逻辑上甚至物理上与所有其他代码分开。它可以在 SOAP 或 XMLRPC 中实现,允许数据库位于物理上独立的服务器上,因此即使网站服务器受到威胁,它也能保持安全。

这也表明完全有可能设计一种安全的脚本语言,从而使数据执行风格的漏洞利用是不可能的。甚至可以扩展现有语言以使漏洞利用变得不可能。只需禁用所有内置的“危险”功能并用安全包装器接口替换它们的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值