Web安全
说到互联网和基于Web的应用程序,在这个领域中存在许多特殊的问题。我们使用互联网的原因是向最广泛的用户销售产品或服务。因此组织机构需要允许互联网上不计其数的实体访问它们的Web 服务器。多数情况下,公司必须打开防火墙上与Web有关的端口(端口80和443)。于是,现在任何可通过这些端口的攻击都将开始入侵。
对互联网提供商而言,应用程序本身也带有神秘色彩。如果你希望通过互联网出售自制的馅饼,那么往往需要显示它们的图片,并允许购买者(通过电子邮件或在线聊天)提出问题。通常,你也需要某种购物车程序来收取客户购买馅饼的货款,还要处理运输和支付渠道问题。所有这些工作都由一个只是想卖馅饼的人来处理。如果你是一名面包师,并且可能不是Web管理员,那么现在就必须依靠其他人来帮助你建立Web站点,同时向这个网站上传适当的应用程序。你应该开发自己的基于PHP或Java的应用程序吗?这样做的好处是显而易见的,开发一个自定义的应用程序可进一步自动化你的业务,但如果你没有掌握开发方法、开发流程、QA、变更控制以及标识风险和脆弱性的知识,那么这其中就包含着巨大风险(特别在第一次开发应用程序时)。
开发自己的Web应用程序之外的另一种备选方案是使用一款现成的应用程序。网络上的许多商业和免费应用程序几乎能满足每种电子商务的需求。这些应用程序由许多实体以各种语言编写,那么我们现在面临的问题是:我们该信任谁呢?这些开发人员会采用你自己使用的开发流程吗?在开发和测试这些应用程序时,开发人员是否考虑到安全问题?这些应用程序在提供功能的同时会引入任何脆弱性吗?你的Web管理员为实现某些功能建议你在站点上使用 Web 应用程序,那么他了解与之相关的安全威胁吗?这些问题不仅让那些想要通过互联网出售馅饼的人头痛,也折磨着金融机构、拍卖站点和每个参与电子商务的人员。
针对Web 环境的特定威胁
本节将分别讨论最常见的脆弱性、威胁和复杂问题:
·管理接口
·身份验证与访问控制
·输入验证
·参数确认
·会话管理
1.管理接口
每个人都希望在咖啡店或在家里穿着睡衣工作,Web 管理员和 Web 开发人员尤其喜爱这种理念。尽管一些系统要求在本地终端上进行管理,但多数情况下,系统都有一个远程管理接口,甚至可通过Web进行管理。对Web管理员而言,虽然这种管理方式可能非常方便,但它也为未授权用户访问系统提供了一个进入点。
自从我们讨论Web以来,在多数人眼中,使用一个基于Web的管理接口(administrative interface)并不是一个好主意。如果我们已经标识这种脆弱性并愿意接受风险,那么管理接口也应至少与Web应用程序或我们提供的服务一样安全(或更安全)。
即使在高度安全的环境中,将身份验证凭证硬编码到管理接口的连接中或激活“记住口令”选项都是一种不良习惯。虽然这确实会使管理员工作起来更方便,但也为偶然发现以上链接的用户(无论他们有什么企图)提供了许多访问机会。
因此,让我们正视现实,大多数商业软件和Web应用程序服务器都默认安装了某种类型的管理控制台。了解这一点,同时记住我们已经讨论过的信息收集技巧,这就足以让组织机构认真对待这种威胁。如果不需要管理接口,就应当禁用这个接口。在开发定制的应用程序时,管理接口更不为人所知,此时应当在策略和措施中考虑这一问题。
应对这种威胁的简单对策是删除管理接口,但这样做会给管理员增加麻烦。使用一个更强大的身份验证机制要优于采用标准的用户名/口令方法。控制哪些系统可建立连接并进行管理也是另一个不错的方法。许多系统允许定义特定的IP地址或网络ID,并只允许从这些工作站进行管理访问。
实际上,最安全的系统管理接口应该是一种带外接口,即使用一条独立的通信通道,以避免系统所运行的环境中存在任何脆弱性。带外接口的一个示例为使用调制解调器连接 Web 服务器,直接拨号进入并配置它使用一个本地接口,而不是使用一个Web 接口通过互联网建立连接。就像在SSH中一样,这个连接应通过一条加密通道建立。
2.身份验证与访问控制
如果你已经通过互联网登录银行、购物、注册课程或在家工作,那么我相信你一定曾经通过一个基于 Web 的应用程序进行登录。从客户或提供商的角度看,身份验证与访问控制都是一个明显的问题。客户希望访问控制机制提供他们期望可信实体所提供的安全性和隐秘性,但不希望这个过程过于复杂。从服务提供商的角度看,他们希望在性能、合规性和成本许可的范围内为客户提供尽可能可靠的安全。因此,从双方的角度看,大多数 Web 应用程序仍使用传统的用户名和口令来控制访问。
在提供一个实体的身份时口令并不提供太多可信性。使用口令的原因是由于它们成本低廉,且已经被构建到已有软件中,用户已经习惯使用它们了。但是,口令并不能证明用户jsmith 确实是 JohnSmith,它们只能证明使用 jsmith这个账户的人输入了正确的口令。认为保存有敏感信息(医疗、金融信息等)的系统是攻击者确定的目标,这种说法并不牵强。通过搜索引擎或者简单使用常见的用户名(如 jsmith)来挖掘用户名并尝试登录这些站点的现象非常普遍。如果你需要在某个Web 站点注册并下载“免费”文档或文件,那么你会使用什么用户名呢?你会使用与其他站点相同的用户名吗?你甚至会使用相同的口令吗?狡猾的攻击者可能通过其他看似友好、提供IQ测试并返回结果或让你参加抽奖的Web站点来挖掘信息。需要记住,未经过培训、容易轻信的用户是组织机构最大的威胁。
许多提供在线银行功能的金融组织都实施多因素身份验证要求。用户可能需要提供用户名、密码和在验证过程中发送到手机或邮箱上的二次性密码。
最后,通过一个安全机制来传送所有身份验证信息是一种最佳做法。通常,这意味着要通过传输层安全(TLS)对口令和通信通道进行加密。然而,一些大型站点仍然没有使用加密的身份验证机制,而将自己暴露在攻击者嗅探用户名和口令的威胁之中。
3.输入验证
Web 服务器像其他任何软件应用程序一样,只做指令告诉它们做的事情。设计Web服务器的目的是通过某种协议来处理请求。如果一个人在 Google 上搜索词组“CISSP”,那么浏览器将使用超文本传输协议(HTTP)发送 https://www.google.com/?q=cissp 的请求。它将参数 q-cissp 发送给google.com域中 www 主机上的 Web应用程序。这种形式的请求称为统一资源定位符(URL)。像计算机领域的其他情况一样,提出请求可以不止一种方法,因为计算机会讲几种不同的“语言”(如二进制、十六进制以及其他许多编码机制),每种编码都被系统当成有效的命令进行解释和处理。验证这些请求被允许是输入验证的一部分工作,而且这通常与某些编码的验证规则相关联。攻击者已找出了如何绕过编码的验证规则的方法。
下面列出了一些输入验证攻击的例子:
·路径或目录遍历 这种攻击也称为“点-点-斜线”,因为它通过在URL中插入几个“/”字符来回溯或遍历本不应通过Web访问的目录,从而实施攻击。命令提示符下的“/”命令告诉系统返回到前一个目录(试着输入“cd/”,看看会有什么结果)。如果一个Web服务器的默认目录为c:\inetpub\www,那么请求“http://www.website.com/scripts/./.J./…windows/system32/cmd.exe?/c+dir+c:\”的URL会将命令系统返回几个目录,直至进入驱动器的根目录,然后请求修改操作系统目录(windows\system32),并运行cmd.exe列出驱动器c:中的全部内容。访问命令行会给攻击者带来大量访问机会。
·Unicode 编码 Unicode是一种行业标准机制,开发它的目的是为了以一种标准的编码格式来表示世界上的10万多个文本字符。Web服务器支持Unicode以支持不同的字符(如中文),并且许多服务器都默认支持Unicode.因此,即使我们告诉系统禁止前面提到的“/”目录遍历请求,但是在应用Unicode的情况下,攻击者不使用“。”,而是通过那个字符的 Unicode表示形式(共3种:%c1%1c、%c0%9v和%c0%af)就仍然可以有效地提出相同的目录遍历请求。这个请求能够悄悄避开确认规则并得到处理。
·URL 编码 不知道你是否曾经注意到,在Web浏览器的URL中,“空格”以%20表示。实际上,%20即表示空格,因为URL中禁止使用空格字符。就像使用Unicode字符的攻击一样,攻击者发现他们能以不同的方式表示字符,从而避开过滤并提出请求。
除了向用户提供静态文件之外,几乎每种Web应用程序都必须接受某种输入。当你使用 Web时,它不断要求你输入信息,如用户名、口令和信用卡资料。对Web 应用程序而言,这些数据只是需要处理的数据,与应用程序中的其他代码没什么两样。通常,这个输入被当成是一个变量,并根据某种逻辑(如IFusername input field=X ANDpasswordinput field=Y THEN Authenticate)插入处理代码中。如果在输入字段中总是输入正确的信息,那么一切将正常运行。但是,如果在其中输入了错误信息,又会出现什么情况呢?开发人员必须考虑各种问题。它们必须假设,有时人们会输入错误信息,他们必须对这种情况进行适当的处理。为了处理这种情况,开发人员往往会编写一个例程,以告诉系统在输入出错时应该如何应对。
客户端验证指在将输入发送回服务器进行处理之前,在客户端进行输入验证。如果在单击Submit 按钮前后遗漏了 Web表单中的一个字段,将立即收到一条消息,通知你忘记填写其中一个字段。此时,你就可以体验到什么是客户端验证。这是一种不错的做法,可防止向服务器发送未完成的请求和服务器返回错误的情况。如果客户端验证是唯一的验证机制,就会出现上述问题。这种情况下,服务器会信任客户端已经正确地完成了它的工作,因而将输入当成有效输入处理。正常情况下,接受这个输入不存在问题。但是,如果攻击者能够拦截客户端与服务器之间的流量并对其进行修改,或者可不使用客户端直接提出非法请求,那么系统迟早会被攻破。
在输入验证相对薄弱的环境中,攻击者可不在输入字段内输入有效输入(如用户名和口令),而是输入特定的操作系统命令,并设法诱使系统运行这些命令。需要记住,你让计算机做什么,它就做什么;如果攻击者能够让计算机运行一条操作系统命令,那么它们会执行该命令,就像其是应用程序一样。如果一个Web应用程序主要用于访问数据库(这样的应用程序有很多),那么它将面临SQL注入的威胁。此时,攻击者不是输入有效输入,而是在输入字段中输入数据库命令。然后,应用程序分析并执行这些命令。攻击者可使用结构化查询语言(SQL)语句避开身份验证并查明一个数据库中的所有记录。
需要记住,系统的各个层次(参见图8-32)都存在它们各自必须确定并修复的脆弱性。
跨站点脚本是另一种类似的探查攻击。在安全社区,它已经替代缓冲区溢出,成为 Web 应用程序的最大威胁。术语“跨站点脚本(XSS)”指的是在一个 Web 站点发现的脆弱性允许攻击者在Web 应用程序中注入恶意代码的攻击。XSS 攻击使攻击者(用客户端脚本语言,如JavaScript)把他们的恶意代码注入脆弱的网页中。随后,不知情的用户在访问这个站点时,恶意代码就会在他们的浏览器中执行,这样可能导致cookie被盗、会话被劫持、恶意代码被执行和访问控制被绕过,或有助于利用浏览器漏洞。下面列出3种不同的XSS脆弱性:
·非持久XSS脆弱性,或者称为反射脆弱性,出现在攻击者欺骗受害者处理一个用流氓脚本编写的 URL,从而偷取受害者敏感信息(cookie,会话ID等)时。这个攻击的原理是利用动态网站上缺少适当的输入或者输出确认。
·持久XSS脆弱性,也称为存储或者第二顺序脆弱性,通常针对的是那些让用户输入存储在数据库或其他任何地方(如论坛、留言板、意见簿等)的数据的网站。攻击者张贴一些包含恶意 JavaScript的文本,在其他用户浏览这些帖子时,它们的浏览器会呈现这个页面并执行攻击者的 JavaScript.
·文件对象模型(Document Object Model,DOM)XSS脆弱性,也叫本地跨站点脚本。DOM是标准结构布局,代表着浏览器中的HTML和XML.在这样的攻击中,像表单字段和cookie这样的文档组件可通过 JavaScript 被引用。攻击者利用 DOM环境来修改最初的客户端JavaScript。这使受害者的浏览器执行由此而导致的JavaScript代码。
大量应用程序都易遭受XSS 攻击。最常见的包括在线论坛、留言板、搜索框、社交网络网站、电子邮件中的嵌入式链接等。虽然跨站点攻击主要针对的是 Web 应用程序脆弱性,但它们也可以用来利用受害者的 Web 浏览器中的脆弱性。一旦系统被攻击者成功攻击,他们可能进一步渗透到网络上的其他系统中或者执行可在整个内部网络上传播的脚本。
这一节讨论的所有攻击都存在错误假定:你可考虑到所有可能到达Web应用程序的输入值,可考虑到特殊编码的数据对应用程序的影响,并认为收到的输入始终有效。解决这些问题的办法在于过滤掉全部“已知的”恶意请求,未经确认绝不相信来自客户端的信息,并执行一个强大的策略,包括在所有应用程序中进行适当的参数检查等。
4.参数确认
参数确认问题类似于前面提到的输入确认问题。参数确认(parameter validation)是指首先确认应用程序收到的值在确定的界限内,然后由服务器应用程序在系统内处理这些值。参数确认与输入确认的主要区别在于,应用程序是否期望用户输入一个值,而不是由应用程序定义的一个环境变量。这个领域的攻击将操纵系统认为客户端无法配置的值,主要原因是接口中没有提供这样一种机制。
在努力提供丰富的终端用户体验的同时,Web应用程序设计人员还必须采用各种机制来追踪任何时候与应用程序相连的数千种不同的Web浏览器。HTTP协议本身并不能为管理用户的连接提供任何帮助,它只是连接到一台服务器,获得HTML代码(HTTP的标记语言)中请求的任何对象(html文件、图片等),然后断开连接或超时。如果浏览器断开连接或超时,那么当它返回时,服务器知道如何识别它吗?如果因为在在线预订机票时必须重新输入自己的所有信息才能查看所有可能的航班,从而导致花费大量的时间,那么你会感到恼怒吗?由于大多数人都会感到生气,因此Web开发人员采用了一种向客户端提交cookie的技术,以帮助服务器“记忆”连接的状态。cookie 并不是一个程序,而是传递并保存在内存中的一些数据(名为会话 cookie)或者一个本地保存的文件(名为永久性cookie),以向服务器返回状态信息。商业Web站点上使用的购物车应用程序就是如何利用 cookie的一个示例。当你在购物车中添加商品时,它们会通过更新系统中的一个会话cookie而始终保留在购物车中。你可能已经注意到,当输入一些Web站点的地址时,屏幕上会出现一条“cookies must beenabled(必须启用cookie)”的消息。
既然多数用户通常都不能访问内存中的会话cookie,那么许多Web开发人员在设计系统时并没有将其视为一个严重威胁。在发生若干次失败的登录尝试后,Web开发人员往往会激活账户锁定策略(如前所述)。如果开发人员使用会话cookie来追踪用户已经尝试登录的次数,那么这种做法就可能存在脆弱性。如果应用程序决定当登录失败超过3次时就锁定客户端,服务器可能向客户端传送一个会话 cookie,并设定一个值(如“允许的登录次数=3”),那么每次登录失败后,服务器都将告诉客户端递减“允许的登录次数”值。如果这个值变为0,那么客户端将指向一个“Your account hasbeen locked out(你的账户已被锁定)”页面。
Web代理是安装在系统上的一款软件,它的目的是拦截本地Web浏览器与 Web服务器之间的所有流量。使用免费的Web代理软件(如 Achilles 或Burp Proxy),攻击者能监控并修改在Web浏览器与Web服务器之间传送的任何信息。在上面的示例中,当服务器通过一个会话cookie告诉客户“允许的登录次数=3”时,如果该信息被攻击者使用以上其中一个代理拦截,并将这个值改为“允许的登录次数-50000”,那么在系统没有实施其他确认机制的情况下,攻击者就能有效地对系统发起蛮力攻击。
使用 Web代理还可以对Web页面使用隐藏字段的做法加以利用。就像它的名称所说明的那样,隐藏字段并不在用户界面上显示,但却包含一个值,它在提交Web表单时传递给服务器。如果Web开发人员将一个Web页面中的商品价格编码成隐藏值,而不是在服务器上引用商品及其价格,那么攻击者就可对这种使用隐藏字段的做法加以利用。攻击者可使用Web代理拦截客户提交的信息,并在将其提交给服务器之前修改其中的值(价格)。实施这种攻击非常容易,假如系统没有执行其他检查,攻击者可修改电子商务购物车指定的新值。
减少与这些威胁有关的风险的对策在于执行足够的参数确认。足够的参数确认包括预先确认和事后确认控制。在客户端/服务器环境中,预先确认控制可部署在客户端,然后向服务器提交请求。即使采用了这些控制,服务器还是应当在应用程序提交请求之前执行并行的预先确认,因为客户端实施的控制通常比服务器少,并且可能已经被攻破或避开。
·预先确认 在提交给应用程序之前,输入控制验证数据格式正确并符合应用程序规范。预先确认的一个示例为表单字段确认,即一个希望收到数字(货币)值的 Web 表单字段不接受字母输入。
·事后确认 确保应用程序的输出符合预期(也就是在预先确定的合理性限制内)。
5.会话管理
前面曾经强调过,管理连接到一个基于Web的应用程序的数千个不同客户端是一项挑战。需要在通过Web交付应用程序之前考虑会话管理。通常,管理客户端会话最常用的方法是给每个连接都分配一个唯一的会话ID.会话ID是一个值,它由客户端随每个请求一起发送给服务器,用于为服务器或应用程序唯一标识客户端。如果攻击者能获得或猜测出一个已经通过身份验证的客户端的会话ID,并将其当作自己的会话ID递交给服务器,那么服务器将受到欺骗,从而使得攻击者能访问客户端的会话。
古老的“绝不要以明文形式传送任何内容”规则确实适用于这种场合。默认情况下,HTTP流量并没有加密,因而无法阻止攻击者嗅探会话ID。因为会话ID往往通过HTTP协议传递和维护,所以应当采用某种方式加以保护。
能预测或猜测会话ID的攻击者也是这种环境的一个威胁。为客户端分配连续的会话ID肯定是错误的。随机的、长度适当的会话ID即可预防会话ID预测。建立某种形式的时间标签或基于时间的确认,可阻止重放攻击(这种攻击是指攻击者截获一个合法会话的流量并重放它,从而是自己的会话通过身份验证)。最后,用于追踪链接状态的所有cookie也应该进行加密。
Web 应用安全原则
鉴于 Web 站点天生暴露的特点,在很多攻击活动中它成为主要攻击目标。因此,对于 Web 开发人员来说,很有必要遵守那些历史悠久且久经考验的原则,从而实现防御黑客的最高水平。Web应用安全原则能够规范编程风格,以及战略性地减少重复出现软件错误和逻辑缺陷的概率,
相当多的网站被攻击利用,其原因就在于粗放性的编程所导致的一些漏洞被黑客利用。伴随着网站数量日益增多,存在漏洞的代码被攻击利用的可能性在急剧增加。
实施安全原则的第一个法宝是分析网站架构。一个网站越清晰、简单,那么分析它的各种安全要素就越容易。一旦对网站进行了战略性分析,用户生成的Web站点输入就需要严格审查。作为一项规则,所有输入必须被认为是不安全的或恶意的,应该在处理之前进行净化处理。同样,由系统产生的所有输出也应该被过滤,以确保私有或敏感数据不被泄露。
此外,使用加密技术将有助于保护 Web 应用程序的输入输出操作。虽然加密的数据可能被恶意用户所截获,但它们只能被那些拥有密钥的人在解密后读取或修改。
在出现错误的情况下,设计的网站应该能以可预知的和不妥协的方式呈现。这一般被称为安全式失败。支持安全式失败的系统可在不暴露内部系统细节的情况下显示友好错误信息。
设计安全功能的一个重要因素是要从人性化角度考虑问题,为实现安全的有效性,程序员甚至可能想让用户在每次点击鼠标时都确认密码,但即使这样Web开发人员也必须维护功能和安全性之间的平衡。繁杂的身份验证技术通常不会在实践中存活太长时间。经验表明,最好的安全措施是那些简单的,直观的和心理上可接受的。
使用“隐匿安全”方法实现安全保护通常是一种糊涂和无效的做法。通过隐藏安全想法创建的过于复杂或令人费解的程序将减少软件介入的机会。虽然晦涩的程序可能需要更长的时间来一点点剖析,这并不能保证自己免于来自果断和坚定攻击者的攻击。因此,保护措施不能仅包括模糊处理。
在最后,重要的是要认识到,即使是最强健的安全技术实施,如果没有战术上的考虑,都会导致一个网站像其最薄弱的环节一样脆弱。
原文链接:http://e-green.gzhu.edu.cn/info/1005/1017.htm
原创文章,作者:优速盾-小U,如若转载,请注明出处:https://www.cdnb.net/bbs/archives/17792