OWASPTOP10WEB安全中文版.docx

上传人:b****3 文档编号:26891320 上传时间:2023-06-23 格式:DOCX 页数:42 大小:219.73KB
下载 相关 举报
OWASPTOP10WEB安全中文版.docx_第1页
第1页 / 共42页
OWASPTOP10WEB安全中文版.docx_第2页
第2页 / 共42页
OWASPTOP10WEB安全中文版.docx_第3页
第3页 / 共42页
OWASPTOP10WEB安全中文版.docx_第4页
第4页 / 共42页
OWASPTOP10WEB安全中文版.docx_第5页
第5页 / 共42页
点击查看更多>>
下载资源
资源描述

OWASPTOP10WEB安全中文版.docx

《OWASPTOP10WEB安全中文版.docx》由会员分享,可在线阅读,更多相关《OWASPTOP10WEB安全中文版.docx(42页珍藏版)》请在冰豆网上搜索。

OWASPTOP10WEB安全中文版.docx

OWASPTOP10WEB安全中文版

OWASPTOP10-2010

开放式Web应用程序安全项目(OWASP,OpenWebApplicationSecurityProject)是一个组织,它提供有关计算机和互联网应用程序的公正、实际、有成本效益的信息。

其目的是协助个人、企业和机构来发现和使用可信赖软件。

OWASP发布了最新的Web应用脆弱性的top10,这是继2007年OWASP对TOP10进行修订后进行的又一次更改,该版本暂定为OWASPTOP10- 2010。

新版本的OWASPTOP10中主要有以下变化:

1.Top10的命名发生了变化。

原先的Top10全称为“Thetop10mostcriticalwebapplicationsecurityvulnerabilities”,即“Web应用的十大关键脆弱性”,现在Top10的全称为“Thetop10mostcriticalwebapplicationsecurityrisks”,即“Web应用的十大关键风险”。

2.OWASPTop10的风险评估方法

 此次Top10的评估是依据OWASP的风险评估方法来对OWASPTOP10排序的。

3.替换了2个风险

 此次Top10与2007年的Top10相比, 在内容上去掉了“MaliciousFileExecution”(恶意文件执行)和“Informationleakageandimpropererrorhandling”(信息泄露及不恰当的错误处理),增加了“Securitymisconfiguration”(错误安全配置)和“Unvalidatedredirectsandforwards”(未验证的重定向和传递)。

 OWASPTOP102007

 OWASPTOP102010

 A2-注入

 A1-注入

 A1-跨站脚本(XSS)

 A2-跨站脚本(XSS)

 A7-错误的认证和会话管理

 A3-错误的认证和会话管理

 A4-不正确的直接对象引用

 A4-不正确的直接对象引用

 A5-伪造跨站请求(CSRF)

 A5-伪造跨站请求(CSRF)

 

 A6-安全性误配置

 A10-限制远程访问失败

 A7-限制远程访问失败

 

 A8-未验证的重定向和传递

 A8-不安全的加密存储

 A9-不安全的加密存储

 A9-不足的传输层保护

 A10-不足的传输层保护

 A3-恶意文件执行

 

 A6-不安全的通讯

 

OWASP风险评估方法

OWASP所选取的10大风险是依据OWASP的风险评估方法,我们从标准的风险模型开始,即风险=可能性*后果,下面我们以以下步骤来说明某个风险的严重程度:

第一步:

识别风险

识别风险作为评估的第一步,我们必须找到与这个风险相关的威胁、相应的攻击方法、隐含在里面的脆弱性以及最终可能造成的后果,当然可能存在多种攻击方法和多种后果,在评估时我们往往会采用最坏选择,这样就能更客观的反应该风险的最终评级;

第二步:

考虑影响可能性的因素

通常,我们不可能很精准的说出某个风险的可能性数值,所以我们一般用高、中、低来表示,而且影响某个风险的可能性的因素有很多,对于每个因素我们用0到9的数值来表示。

类别

因素

分项

分值

威胁

技能要求

无需技能

1

需要一些技术

3

高级的计算机用户

4

需要网络和编程技术

6

安全渗透技术

9

成功攻击后攻击者的益处

很低或无益

1

可能会有回报

4

高回报

9

所需资源或机会

需要很大资源或高权限访问

0

需要特定的访问权限和特定的资源

4

需要一些访问权限和资源

7

无需权限或资源

9

所需的攻击者的角色

开发者

2

系统管理员

2

内部用户

4

合作伙伴

5

认证用户

6

匿名Internet用户

9

脆弱性

发现该弱点的难易度

技术上不可行

1

困难

3

容易

7

可用自动化工具发现

9

利用该弱点的难易度

只是理论上的

1

困难

3

容易

5

可用自动化工具实现

9

该弱点的流行度

不为人知

1

隐藏

4

明显

6

公众皆知

9

入侵被察觉的可能性

应用程序主动检测

1

记录日志并审核

3

记录日志未审核

8

无日志

9

第三步:

考虑影响后果的因素

在考虑攻击后果的时候,我们会考虑两种后果,一种是应用的“技术后果”,它所使用的数据,提供的功能等等,另一种就是它的“商业后果”,显然后者则更为重要,但往往后者难以估量,所以我们需要尽可能从技术上去考虑,进而来估计后者的数据。

类别

因素

分项

分值

技术后果

保密性损失

很少的非敏感的数据泄漏

2

很少的敏感数据泄漏

6

大量的非敏感数据泄漏

6

大量的敏感数据泄漏

9

A1-注入

注入往往是应用程序缺少对输入进行安全性检查所引起的,攻击者把一些包含指令的数据发送给解释器,解释器会把收到的数据转换成指令执行。

常见的注入包括SQL注入,OSShell,LDAP,XPath,Hibernate等等,其中SQL注入尤为常见。

这种攻击所造成的后果往往很大,一般整个数据库的信息都能被读取或篡改,通过SQL注入,攻击者甚至能够获得更多的包括管理员的权限。

防范SQL注入——编程篇

SQL注入往往是在程序员编写包含用户输入的动态数据库查询时产生的,但其实防范SQL注入的方法非常简单。

程序员只要a)不再写动态查询,或b)防止用户输入包含能够破坏查询逻辑的恶意SQL语句,就能够防范SQL注入。

在这篇文章中,我们将会说明一些非常简单的防止SQL注入的方法。

  我们用以下Java代码作为示例:

Stringquery="SELECTaccount_balanceFROMuser_dataWHEREuser_name="

  +request.getParameter("customerName");

 

try{

Statementstatement=connection.createStatement(…);

ResultSetresults=Statement.executeQuery(query);

}

  在以上代码中,我们可以看到并未对变量customerName做验证,customerName的值可以直接附在query语句的后面传送到数据库执行,则攻击者可以将任意的SQL语句注入。

  防范方法1:

参数化查询

  参数化查询是所有开发人员在做数据库查询时首先需要学习的,参数化查询迫使所有开发者首先要定义好所有的SQL代码,然后再将每个参数逐个传入,这种编码风格就能够让数据库辨明代码和数据。

  参数化查询能够确保攻击者无法改变查询的内容,在下面修正过的例子中,如果攻击者输入了UsrID是“’or‘1‘=’1”,参数化查询会去查找一个完全满足名字为‘or‘1‘=’1的用户。

  对于不同编程语言,有一些不同的建议:

  JavaEE——使用带绑定变量的PreparedStatement();

  .Net——使用带绑定变量的诸如SqlCommand()或OleDbCommand()的参数化查询;

  PHP——使用带强类型的参数化查询PDO(使用bindParam());

  Hibernate——使用带绑定变量的createQuery()。

  Java示例:

Stringcustname=request.getParameter("customerName");

Stringquery="SELECTaccount_balanceFROMuser_dataWHEREuser_name=?

";

 

PreparedStatementpstmt=connection.prepareStatement(query);

Pstmt.setString(1,custname);

ResultSetresults=pstmt.executeQuery();

  C#.Net示例:

Stringquery="SELECTaccount_balanceFROMuser_dataWHEREuser_name=?

";

Try{    

   OleDbCommandcommand=newOleDbCommand(query,connection);

   command.Parameters.Add(newOleDbParameter("customerName",CustomerName.Text));

   OleDbDataReaderreader=command.ExecuteReader();

  }catch(OleDbExceptionse){

  //errorhandling

}

防范方法2:

存储过程

  存储过程和参数化查询的作用是一样的,唯一的不同在于存储过程是预先定义并存放在数据库中,从而被应用程序调用的。

  Java存储过程示例:

Stringcustname=request.getParameter("customerName");

try{

     CallableStatementcs=connection.prepareCall("callsp_getAccountBalance(?

)}");

     cs.setString(1,custname);

     Resultresults=cs.executeQuery();

}catch(SQLExceptionse){

//errorhandling

}

 VB.Net存储过程示例:

Try

DimcommandAsSqlCommand=newSqlCommand("sp_getAccountBalance",connection)

 command.CommandType=CommandType.StoredProcedure

 command.Parameters.Add(newSqlParameter("@CustomerName",CustomerName.Text))

 DimreaderAsSqlDataReader=command.ExecuteReader()

 ‘…

CatchseAsSqlException

 ‘errorhandling

EndTry

防范方法3:

对所有用户输入进行转义

  我们知道每个DBMS都有一个字符转义机制来告知DBMS输入的是数据而不是代码,如果我们将所有用户的输入都进行转义,那么DBMS就不会混淆数据和代码,也就不会出现SQL注入了。

  当然,如果要采用这种方法,那么你就需要对所使用的数据库转义机制,也可以使用现存的诸如OWASPESAPI的escapingroutines。

ESAPI目前是基于MySQL和Oracle的转义机制的,使用起来也很方便。

一个Oracle的ESAPI的使用示例如下:

ESAPI.encoder().encodeForSQL(newOracleCodec(),queryparam);

  那么,假设你有一个要访问Oracle数据库的动态查询代码如下:

Stringquery="SELECTuser_idFROMuser_dataWHEREuser_name=‘"+req.getParameter("userID")+"’anduser_password=‘"+req.getParameter("pwd")+"’";

try{

     Statementstatement=connection.createStatement(…);

     ResultSetresults=statement.executeQuery(query);

}

 那么,你就必须重写你的动态查询的第一行如下:

CodecORACLE_CODEC=newOracleCodec();

Stringquery="SELECTuser_idFROMuser_dataWHEREuser_name=‘"+

ESAPI.encoder().encodeForSQL(ORACLE_CODEC,req.getParameter("userID"))+"’anduser_password=‘"+

ESAPI.encoder().encodeForSQL(ORACLE_CODEC,req.getParameter("pwd"))+"’";

  当然,为了保证自己代码的可读性,我们也可以构建自己的OracleEncoder:

Encodere=newOracleEncoder();

Stringquery="SELECTuser_idFROMuser_dataWHEREuser_name=‘"

     +oe.encode(req.getParameter("userID"))+"’anduser_password=‘"

     +oe.encode(req.getParameter("pwd"))+"’";

  除了上面所说的三种防范方法以外,我们还建议可以用以下两种附加的方法来防范SQL注入:

最小权限法、输入验证白名单法。

  最小权限法:

  为了避免注入攻击对数据库造成的损害,我们可以把每个数据库用户的权限尽可能缩小,不要把DBA或管理员的权限赋予你应用程序账户,在给用户权限时是基于用户需要什么样的权限,而不是用户不需要什么样的权限。

当一个用户只需要读的权限时,我们就只给他读的权限,当用户只需要一张表的部分数据时,我们宁愿另建一个视图让他访问。

  如果你的策略是都是用存储过程的话,那么仅允许应用程序的账户执行这些查询,而不给他们直接访问数据库表的权限。

诸如此类的最小权限法能够在很大程度上保证我们数据库的安全。

  输入验证白名单法:

  输入验证能够在数据传递到SQL查询前就察觉到输入是否正确合法,采用白名单而不是黑名单则能在更大程度上保证数据的合法性。

防范SQL注入——测试篇

对于测试人员来说,如何测试SQL注入漏洞是否存在呢?

  首先,我们将SQL注入攻击能分为以下三种类型:

  Inband:

数据经由SQL代码注入的通道取出,这是最直接的一种攻击,通过SQL注入获取的信息直接反映到应用程序的Web页面上;

  Out-of-band:

数据通过不同于SQL代码注入的方式获得(譬如通过邮件等)

  推理:

这种攻击是说并没有真正的数据传输,但攻击者可以通过发送特定的请求,重组返回的结果从而得到一些信息。

  不论是哪种SQL注入,攻击者都需要构造一个语法正确的SQL查询,如果应用程序对一个不正确的查询返回了一个错误消息,那么就和容易重新构造初始的查询语句的逻辑,进而也就能更容易的进行注入;如果应用程序隐藏了错误信息,那么攻击者就必须对查询逻辑进行反向工程,即我们所谓的“盲SQL注入”

  黑盒测试及示例:

  这个测试的第一步是理解我们的应用程序在什么时候需要访问数据库,典型的需要访问数据库的时机是:

  认证表单:

输入用户名和密码以检查是否有权限

  搜索引擎:

提交字符串以从数据库中获取相应的记录

  电子商务站点:

获取某类商品的价格等信息

  作为测试人员,我们需要列对所有输入域的值可能用于查询的字段做一个表单,包括那些POST请求的隐含字段,然后截取查询语句并产生错误信息。

第一个测试往往是用一个单引号“‘”或是分号“;”,前者在SQL中是字符串终结符,如果应用程序没有过滤,则会产生一条错误信息;后者在SQL中是一条SQL语句的终结符,同样如果没有过滤,也会产生错误信息。

在MicrosoftSQLServer中,返回的错误信息一般是这样:

MicrosoftOLEDBProviderforODBCDriverserror‘80040e14’

[Microsoft][ODBCSQLServerDriver][SQLServer]Unclosedquotationmarkbeforethecharacterstring‘’.

/target/target.asp,line113

  同样可用于测试的还有“--”以及SQL中的一些诸如“AND”的关键字,通常很常见的一种测试是在要求输入为数字的输入框中输入字符串,会返回如下的错误信息:

MicrosoftOLEDBProviderforODBCDriverserror‘80040e07’

[Microsoft][ODBCSQLServerDriver][SQLServer]Syntaxerrorconvertingthevarcharvalue‘tester’toacolumnofdatatypeint.

/target/target.asp,line113

  类似上面这样的出错返回信息能让我们知道很多数据库的信息,通常不会返回那么多信息,会返回诸如“500ServerError”的信息,那就需要“盲SQL注入”了。

注意,我们需要对所有可能存在SQL注入漏洞的输入域进行测试,并且在每个测试用例时只变化一个域的值,从而才能找到真正存在漏洞的输入域。

下面我们看一下标准的SQL注入测试是怎样的。

  我们以下面的SQL查询为例:

  SELECT*FROMUsersWHEREUsername='$username'ANDPassword='$password'

  如果我们在页面上输入以下的用户名和密码:

  $username=1'or'1'='1

  $password=1'or'1'='1

  那么整个查询语句就变为:

  SELECT*FROMUsersWHEREUsername='1'OR'1'='1'ANDPassword='1'OR'1'='1'

  假设参数值是通过GET方法传递到服务器的,且域名为,那么我们的访问请求就是:

  

  对上面的SQL语句作简单分析后我们就知道由于该语句永远为真,所以肯定会返回一些数据,在这种情况下实际上并未验证用户名和密码,并且在某些系统中,用户表的第一行记录是管理员,那这样造成的后果则更为严重。

  另外一个查询的例子如下:

  SELECT*FROMUsersWHERE((Username='$username')AND(Password=MD5('$password')))

  在这个例子中,存在两个问题,一个是括号的用法,还有一个是MD5哈希函数的用法。

对于第一个问题,我们可以很容易找到缺失的右括号解决,对于第二个问题,我们可以想办法使第二个条件失效。

我们在查询语句的最后加上一个注释符以表示后面的都是注释,常见的注释起始符是/*(在Oracle中是--),也就是说,我们用如下的用户名和密码:

  $username=1'or'1'='1'))/*

  $password=foo

  那么整条SQL语句就变为:

  SELECT*FROMUsersWHERE((Username='1'or'1'='1'))/*')AND(Password=MD5('$password')))

  我们的URL请求就变为:

  

Union查询SQL注入测试

  还有一种测试是利用Union的,利用Union可以连接查询,从而从其他表中得到信息,假设我们有如下的查询:

  SELECTName,Phone,AddressFROMUsersWHEREId=$id

  然后我们设置id的值为:

  $id=1UNIONALLSELECTcreditCardNumber,1,1FROMCreditCarTable

  那么整体的查询就变为:

  SELECTName,Phone,AddressFROMUsersWHEREId=1UNIONALLSELECTcreditCardNumber,1,1FROMCreditCarTable

  显然这样就能得到所有信用卡用户的信息。

  盲SQL注入测试

  在上面我们提到过盲SQL注入,即blindSQLinjection,它意味着对于某个操作我们得不到任何信息,通常这是由于程序员已经编写了特定的出错返回页面,从而隐藏了数据库结构的信息。

  利用推理方法,有时候我们能够恢复特定字段的值。

这种方法通常采用一组对服务器的布尔查询,依据返回的结果来推断结果的含义。

仍然延续上面的,有一个参数名为id,那么我们输入以下url请求:

  

  显然由于语法错误,我们会得到一个预先定义好的出错页面,假设服务器上的查询语句为SELECTfield1,field2,field3FROMUsersWHEREId='$Id',假设我们想要得到用户名字段的值,那么通过一些函数,我们就可以逐字符的读取用户名的值。

在这里我们使用以下的函数:

  SUBSTRING(text,start,length),ASCII(char),LENGTH(text)

  我们定义id为:

  $Id=1'ANDASCII(SUBSTRING(username,1,1))=97AND'1'='1

  那么最终的SQL查询语句为:

  SELECTfield1,field2,field3FROMUsersWHEREId='1'ANDASCII(SUBSTRING(username,1,1))=97AND'1'='1'

  那么,如果在数据库中有用户名的第一个字符的ASCII码为97的话,那么我们就能得到一个真值,那么我们就继续寻找该用户名的下一个字符;如果没有的话,那么我们就递增猜测第一个字符的ASCII码为98的用户名,这样反复下去就能判断出合法的用户名。

  那么,什么时候我们可以结束推理呢,我们假设id的值为:

  $Id=1'ANDLENGTH(username)=NAND'1'='1

  其中N是我们到目前为止已经分析的字符数目,那么整体的sql查询为:

  SELECTfield1,field2,field3FROMUs

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 药学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1