门户网站开发安全须知
1. SQL注入
1.1 什么是SQL注入
SQL 注入是一种攻击方式,在这种攻击方式中,恶意代码被插入到字符串中,然后将该字符串传递到数据库的实例以进行分析和执行。任何构成 SQL 语句的过程都应进行注入漏洞检查,因为数据库将执行其接收到的所有语法有效的查询。
例如:以下java代码就会产生sql注入漏洞,以下sql为从客户端获取要查询的id,通过id查询相关的记录。
String id = request.getParameter("id");
String sql = "select * from test_table where id = ‘ " + id + " ’ ";
DAO dao = DaoUtil.getMHWZDao();
List list = dao.query(sql);
但是,如果客户端的id不是123之类的一般数字,而是123'; drop table test_table--
这样,sql的值就变成了
select * from test_table where id = ‘123’;drop table test_table;
或者id的值为123’ or 1=1,这样sql的值就变成了
select * from test_table where id = ‘123’ or 1=1
这样,通过SQL注入以后的查询语句就与原来开发者的意图完全不同了。此类语句在进行登录密码验证的时候危害尤其大,会使登录形同虚设。从而使攻击者可以使用管理员的用户登录系统进行恶意操作。
1.2 SQL注入漏洞有什么危害
未经授权状况下操作数据库中的数据
恶意篡改网页内容
恶意添加系统帐号或数据库使用者帐号
网页挂木马
泄露站点数据库的敏感信息
1.3 如何发现SQL注入漏洞
目前有很多免费的工具可以测试一个URL或者一个网站是否存在SQL注入漏洞。
Linux下五大著名的免费SQL注入漏洞扫描工具
http://hi.baidu.com/larrially/blog/item/81b45523c41555549822ed9e.html
扫描器详细介绍
http://sec.chinabyte.com/120/8589620_1.shtml
前15名免费SQL注入扫描工具
http://blog.chinaunix.net/u1/46222/showart_1722228.html
1.4 如何防止SQL注入漏洞
采用预编译sql进行数据库操作
String sql = "select * from test_table where id=?";
采用上述方法可以有效防止sql注入漏洞
1.5 参考资料
SQL注入漏洞全接触
http://tieba.baidu.com/f?kz=217546563
sql注入
http://baike.baidu.com/view/3896.htm
SQL注入攻击的种类和防范手段
http://tech.sina.com.cn/s/2008-06-24/1305706080.shtml
SQL注入渗透某网络安全公司的网站全过程
http://www.cnblogs.com/lgms2008/archive/2007/06/25/794802.html
一次有趣的SQL注入攻击
http://www.heibai.net/article/info/info.php?infoid=32090
2. 跨站脚本漏洞(XSS)
2.1 什么是跨站脚本漏洞
跨站脚本攻击是指在远程WEB页面的html代码中插入具有恶意目的代码,用户误认为该页面是可信赖的,当用户打开该页面,浏览器会自动下载恶意代码,运行其中的脚本。
例如:在搜索中,一般都将用户的搜索关键字显示在搜索的结果页面,做法如下:
http://www.abc.com/search.jsp?key=关键字
String key = request.getParameter(“key");
在页面占用会使用<%=key%>来显示用户输入的关键字。
但是如果用户输入的key=关键字<script>alert(123)</script>,此时就会出现跨站脚本攻击的情况了。见下图:
2.2 跨站脚本漏洞有什么危害
窃取Cookie
在受害用户面前假冒成Web应用程序(钓鱼攻击)
在Web应用程序面前假冒成受害用户
2.3 如何发现跨站脚本攻击
通过人工尝试是否存在跨站脚本攻击
通过分析url参数和结果页面查看是否存在脚本漏洞
通过工具进行扫描
通过专业工具进行扫描,以更快的速度分析网站是否存在跨站脚本漏洞
2.4 如何防止跨站脚本攻击
过滤<、>、’、”、\、(、)、等敏感字符。
屏蔽get请求,此办法可以屏蔽一部分攻击。
采用com.chinacreator.mhwz.util.XssUtils类的xssFilter方法可以进行过滤
所有的request参数都要使用上述方法进行过滤,不管是否显示在页面上,因为当前虽然不显示,但是不能保证以后需求变更或升级的时候就不会不显示,要消除一切隐患。
2.5 参考资料
也谈跨站脚本攻击与防御
http://www.xfocus.net/articles/200607/874.html
跨站脚本攻击(XSS)
http://blog.csdn.net/abandonship/archive/2008/11/14/3296735.aspx
让你全面了解跨站脚本攻击的12问答
http://www.enet.com.cn/article/2009/0615/A20090615485780.shtml
跨站攻击问答FAQ
http://blog.csdn.net/amh/archive/2004/11/13/180579.aspx
跨站脚本攻击深入解析
http://netsecurity.51cto.com/art/200903/113648.htm
跨站攻击全解析
http://www4.it168.com/jtzt/shenlan/safe/xss/
跨站脚本XSS
http://huaidan.org/archives/3181.html
3. 服务器信任跨越
3.1 什么是服务器信任跨越
在html文件中,可以通过调用远端http请求的方式将请求解析到不安全的URL。
3.2 服务器信任跨越有什么危害
1. 非法进入和设置服务器信息。
2. 加载远程不安全或者恶意文件。
3. 造成钓鱼攻击。
3.3 如何发现服务器信任跨越
1. 通过工具扫描。
2. 手工测试非法url是否可以通过验证。
3.4 如何防止服务器信任跨越
1. 检查用户输入的地址。
2. 检查URL的合法性。
4. 存在默认/管理目录
4.1 什么是存在默认/管理目录
系统使用了第三方软件,一般用于第三方软件的部署和控制功能,其中,可能包含用户登录界面。
4.2 存在默认/管理目录有什么危害
1. 攻击者可以通过默认目录访问改目录下的文件发现系统漏洞,从而进一步攻击。
2. 使用密码破解工具,破解用户密码。
4.3 如何发现存在默认目录/管理
1. 直接测试第三方软件的默认目录,如weblogic的默认目录为/console
2. 使用工具扫描。
4.4 如何防止存在默认目录/管理
1. 将默认目录进行删除或改名。
2. 禁止未授权用户访问。
5. 默认登录页面
这个其实不算是一个漏洞,但是在webRavor扫描过程中会进行此项的检查,会尝试访问login.jsp这样的地址,如果存在,系统会认为有这个弱点。
具体的逻辑为:系统的登录页面是不应该暴露给普通用户的。
6. 系统中存在上传脚本
如果系统中存在上传文件功能,且不要登录,那么此项弱点一定会被扫描到,出现这个弱点,并不一定就代表系统中存在漏洞,扫描报告只是指出,系统中存在上传脚本,即存在上传功能的程序,而程序有没有问题,就要再次核实,扫描只是指出有这个功能而已。
针对上传功能,一定要检查上传文件的类型,不要让用户上传任意类型的文件。不要向用户暴露上传文件的路径,如果这两项同时满足,系统很容易被攻击。
7. 服务器信息泄露
7.1 什么是服务器信息泄露
服务器信息泄露是指在http请求中,服务器向客户端发送的内容包括了部分服务器的配置信息,比如系统使用的中间件的名称及版本号、web服务器的软件名称及版本号,服务器采用的相关编程技术等。
服务器应尽可能少的返回相关信息,见下图。
下图为访问北京移动,获取的服务器信息及web server信息。
下图为访问139邮箱返回的信息。
7.2 服务器信息泄露有什么危害
恶意攻击者可以通过服务器返回的相关信息进行非法操作,如当服务器返回了某软件的名称及版本号,此时,恶意攻击者可以通过搜索该软件存在的漏洞,从而进行恶意攻击。
7.3 如何发现服务器信息泄露
1. 进行工具扫描
2. 通过第三方软件进行查看http头信息。
3. Web开发必备工具:Firefox、web developer、firebug、httpwatch。
7.4 如何防止服务器信息泄露
对服务器的配置进行一一核查,将不必要的信息进行屏蔽。
8. 服务器目录泄露
8.1 什么是服务器目录泄露
服务器目录泄露是只没有限制用户对目录的访问,如果用户访问的目录没有默认文件可以展示,则将此目录下的所有文件以列表的方式进行展示,如下图。
http://www.apache.org/dist/httpd/binaries/
正常情况下,应该提示403错误。
8.2 服务器目录泄露有什么危害
1. 泄露服务器的文件目录结构。
2. 造成敏感文件被查看。
8.3 如何发现服务器目录泄露
查看服务器是否支持目录遍历。
8.4 如何防止服务器目录泄露
禁止服务器进行目录遍历。
增加默认403,404,500,503等页面
9. 服务器存在备份文件
此类弱点主要原因是在服务器上直接备份文件,如将index.jsp备份为index.jsp.bak,此类备份容易被工具或者认为进行试探,一旦存在此类文件,服务器会以文本方式进行展示,这样文件的内容就一览无余,恶意攻击者可以从文件内容中得到对他们有用的信息。
解决办法:不直接在服务器进行备份或者将备份的文件命名为比较复杂且不易猜测的名字。
10. 跨站请求伪造(CSRF)
10.1 什么是跨站请求伪造
CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。
CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。
10.2 跨站请求伪造有什么危害
跨站请求伪造是跨站脚本攻击的一种深入利用,它的危害性更大。如:给自己提升权限,增加管理员等。可以通过网上的一个案例说明这种攻击的危害:Bob在自己的电脑上刚刚查看完自己的银行A账户余额,然后比较无聊就跑到一个公开的BBS上灌水,当他看到一篇“银行A的内部照片”的帖子,很有兴趣的打开这个帖子想看看自己信任的银行A的内部图片是啥样子的,殊不知,这其实是一个attacker精心设计的骗局。在这个帖子中确实有几个图片,看上去真的像是银行A的照片,但是其中有个图片没显示出来,Bob以为是自己网速太慢,导致这个图片没有加载进来,也没在意。只是对这些并不是十分满意的照片摇摇头,就关了这个帖子。几天后,Bob猛然发现自己在银行A的账户上少了1000元,到底是怎么了?
设想一下,Alice编写了一个在Bob的银行站点上进行取款的form提交的链接,并将此链接作为图片tag。如果Bob的银行在cookie中保存他的授权信息,并且此cookie没有过期,那么当Bob的浏览器尝试装载图片时将提交这个取款form和他的cookie,这样在没经Bob同意的情况下便授权了这次事务。
10.3 跨站请求伪造的原理
下图简单阐述了CSRF攻击的思想:
从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤:
1.登录受信任网站A,并在本地生成Cookie。
2.在不登出A的情况下,访问危险网站B。
看到这里,你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证以下情况不会发生:
1.你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。
2.你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了......)
3.上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。
上面大概地讲了一下CSRF攻击的思想,下面我将用几个例子详细说说具体的CSRF攻击,这里我以一个银行转账的操作作为例子(仅仅是例子,真实的银行网站没这么傻:>)
示例1:
银行网站A,它以GET请求来完成银行转账的操作,如:http://www.mybank.com/Transfer.php?toBankId=11&money=1000
危险网站B,它里面有一段HTML的代码如下:
<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>
首先,你登录了银行网站A,然后访问危险网站B,噢,这时你会发现你的银行账户少了1000块......
为什么会这样呢?原因是银行网站A违反了HTTP规范,使用GET请求更新资源。在访问危险网站B的之前,你已经登录了银行网站A,而B中的<img>以GET的方式请求第三方资源(这里的第三方就是指银行网站了,原本这是一个合法的请求,但这里被不法分子利用了),所以你的浏览器会带上你的银行网站A的Cookie发出Get请求,去获取资源“http://www.mybank.com/Transfer.php?toBankId=11&money=1000”,结果银行网站服务器收到请求后,认为这是一个更新资源操作(转账操作),所以就立刻进行转账操作......
示例2:
为了杜绝上面的问题,银行决定改用POST请求完成转账操作。
银行网站A的WEB表单如下:
<form action="Transfer.php" method="POST">
<p>ToBankId: <input type="text" name="toBankId" /></p>
<p>Money: <input type="text" name="money" /></p>
<p><input type="submit" value="Transfer" /></p>
</form>
后台处理页面Transfer.php如下:
<?php
session_start();
if (isset($_REQUEST['toBankId'] && isset($_REQUEST['money']))
{
buy_stocks($_REQUEST['toBankId'], $_REQUEST['money']);
}
?>
危险网站B,仍然只是包含那句HTML代码:
<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>
和示例1中的操作一样,你首先登录了银行网站A,然后访问危险网站B,结果.....和示例1一样,你再次没了1000块~T_T,这次事故的原因是:银行后台使用了$_REQUEST去获取请求的数据,而$_REQUEST既可以获取GET请求的数据,也可以获取POST请求的数据,这就造成了在后台处理程序无法区分这到底是GET请求的数据还是POST请求的数据。在PHP中,可以使用$_GET和$_POST分别获取GET请求和POST请求的数据。在JAVA中,用于获取请求数据request一样存在不能区分GET请求数据和POST数据的问题。
示例3:
经过前面2个惨痛的教训,银行决定把获取请求数据的方法也改了,改用$_POST,只获取POST请求的数据,后台处理页面Transfer.php代码如下:
<?php
session_start();
if (isset($_POST['toBankId'] && isset($_POST['money']))
{
buy_stocks($_POST['toBankId'], $_POST['money']);
}
?>
然而,危险网站B与时俱进,它改了一下代码:
<html>
<head>
<script type="text/javascript">
function steal()
{
iframe = document.frames["steal"];
iframe.document.Submit("transfer");
}
</script>
</head>
<body onload="steal()">
<iframe name="steal" display="none">
<form method="POST" name="transfer" action="http://www.myBank.com/Transfer.php">
<input type="hidden" name="toBankId" value="11">
<input type="hidden" name="money" value="1000">
</form>
</iframe>
</body>
</html>
如果用户仍是继续上面的操作,很不幸,结果将会是再次不见1000块......因为这里危险网站B暗地里发送了POST请求到银行!
总结一下上面3个例子,CSRF主要的攻击模式基本上是以上的3种,其中以第1,2种最为严重,因为触发条件很简单,一个<img>就可以了,而第3种比较麻烦,需要使用JavaScript,所以使用的机会会比前面的少很多,但无论是哪种情况,只要触发了CSRF攻击,后果都有可能很严重。
理解上面的3种攻击模式,其实可以看出,CSRF攻击是源于WEB的隐式身份验证机制!WEB的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的!
10.4 如何防止跨站请求伪造
屏蔽get请求,服务器只接受post请求,对于get请求返回404页面或者错误提示。
10.5 参考资料
深入解析跨站请求伪造漏洞
http://www.05112.com/Article/200901/22100.html
浅谈CSRF攻击方式
http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html
Web安全测试之跨站请求伪造(CSRF)篇
http://blog.ixpub.net/html/46/1772146-374525.html
|
门户网站开发安全须知
1. SQL注入
1.1 什么是SQL注入
SQL 注入是一种攻击方式,在这种攻击方式中,恶意代码被插入到字符串中,然后将该字符串传递到数据库的实例以进行分析和执行。任何构成 SQL 语句的过程都应进行注入漏洞检查,因为数据库将执行其接收到的所有语法有效的查询。
例如:以下java代码就会产生sql注入漏洞,以下sql为从客户端获取要查询的id,通过id查询相关的记录。
String id = request.getParameter("id");
String sql = "select * from test_table where id = ‘ " + id + " ’ ";
DAO dao = DaoUtil.getMHWZDao();
List list = dao.query(sql);
但是,如果客户端的id不是123之类的一般数字,而是123'; drop table test_table--
这样,sql的值就变成了
select * from test_table where id = ‘123’;drop table test_table;
或者id的值为123’ or 1=1,这样sql的值就变成了
select * from test_table where id = ‘123’ or 1=1
这样,通过SQL注入以后的查询语句就与原来开发者的意图完全不同了。此类语句在进行登录密码验证的时候危害尤其大,会使登录形同虚设。从而使攻击者可以使用管理员的用户登录系统进行恶意操作。
1.2 SQL注入漏洞有什么危害
未经授权状况下操作数据库中的数据
恶意篡改网页内容
恶意添加系统帐号或数据库使用者帐号
网页挂木马
泄露站点数据库的敏感信息
1.3 如何发现SQL注入漏洞
目前有很多免费的工具可以测试一个URL或者一个网站是否存在SQL注入漏洞。
Linux下五大著名的免费SQL注入漏洞扫描工具
http://hi.baidu.com/larrially/blog/item/81b45523c41555549822ed9e.html
扫描器详细介绍
http://sec.chinabyte.com/120/8589620_1.shtml
前15名免费SQL注入扫描工具
http://blog.chinaunix.net/u1/46222/showart_1722228.html
1.4 如何防止SQL注入漏洞
采用预编译sql进行数据库操作
String sql = "select * from test_table where id=?";
采用上述方法可以有效防止sql注入漏洞
1.5 参考资料
SQL注入漏洞全接触
http://tieba.baidu.com/f?kz=217546563
sql注入
http://baike.baidu.com/view/3896.htm
SQL注入攻击的种类和防范手段
http://tech.sina.com.cn/s/2008-06-24/1305706080.shtml
SQL注入渗透某网络安全公司的网站全过程
http://www.cnblogs.com/lgms2008/archive/2007/06/25/794802.html
一次有趣的SQL注入攻击
http://www.heibai.net/article/info/info.php?infoid=32090
2. 跨站脚本漏洞(XSS)
2.1 什么是跨站脚本漏洞
跨站脚本攻击是指在远程WEB页面的html代码中插入具有恶意目的代码,用户误认为该页面是可信赖的,当用户打开该页面,浏览器会自动下载恶意代码,运行其中的脚本。
例如:在搜索中,一般都将用户的搜索关键字显示在搜索的结果页面,做法如下:
http://www.abc.com/search.jsp?key=关键字
String key = request.getParameter(“key");
在页面占用会使用<%=key%>来显示用户输入的关键字。
但是如果用户输入的key=关键字<script>alert(123)</script>,此时就会出现跨站脚本攻击的情况了。见下图:
2.2 跨站脚本漏洞有什么危害
窃取Cookie
在受害用户面前假冒成Web应用程序(钓鱼攻击)
在Web应用程序面前假冒成受害用户
2.3 如何发现跨站脚本攻击
通过人工尝试是否存在跨站脚本攻击
通过分析url参数和结果页面查看是否存在脚本漏洞
通过工具进行扫描
通过专业工具进行扫描,以更快的速度分析网站是否存在跨站脚本漏洞
2.4 如何防止跨站脚本攻击
过滤<、>、’、”、\、(、)、等敏感字符。
屏蔽get请求,此办法可以屏蔽一部分攻击。
采用com.chinacreator.mhwz.util.XssUtils类的xssFilter方法可以进行过滤
所有的request参数都要使用上述方法进行过滤,不管是否显示在页面上,因为当前虽然不显示,但是不能保证以后需求变更或升级的时候就不会不显示,要消除一切隐患。
2.5 参考资料
也谈跨站脚本攻击与防御
http://www.xfocus.net/articles/200607/874.html
跨站脚本攻击(XSS)
http://blog.csdn.net/abandonship/archive/2008/11/14/3296735.aspx
让你全面了解跨站脚本攻击的12问答
http://www.enet.com.cn/article/2009/0615/A20090615485780.shtml
跨站攻击问答FAQ
http://blog.csdn.net/amh/archive/2004/11/13/180579.aspx
跨站脚本攻击深入解析
http://netsecurity.51cto.com/art/200903/113648.htm
跨站攻击全解析
http://www4.it168.com/jtzt/shenlan/safe/xss/
跨站脚本XSS
http://huaidan.org/archives/3181.html
3. 服务器信任跨越
3.1 什么是服务器信任跨越
在html文件中,可以通过调用远端http请求的方式将请求解析到不安全的URL。
3.2 服务器信任跨越有什么危害
1. 非法进入和设置服务器信息。
2. 加载远程不安全或者恶意文件。
3. 造成钓鱼攻击。
3.3 如何发现服务器信任跨越
1. 通过工具扫描。
2. 手工测试非法url是否可以通过验证。
3.4 如何防止服务器信任跨越
1. 检查用户输入的地址。
2. 检查URL的合法性。
4. 存在默认/管理目录
4.1 什么是存在默认/管理目录
系统使用了第三方软件,一般用于第三方软件的部署和控制功能,其中,可能包含用户登录界面。
4.2 存在默认/管理目录有什么危害
1. 攻击者可以通过默认目录访问改目录下的文件发现系统漏洞,从而进一步攻击。
2. 使用密码破解工具,破解用户密码。
4.3 如何发现存在默认目录/管理
1. 直接测试第三方软件的默认目录,如weblogic的默认目录为/console
2. 使用工具扫描。
4.4 如何防止存在默认目录/管理
1. 将默认目录进行删除或改名。
2. 禁止未授权用户访问。
5. 默认登录页面
这个其实不算是一个漏洞,但是在webRavor扫描过程中会进行此项的检查,会尝试访问login.jsp这样的地址,如果存在,系统会认为有这个弱点。
具体的逻辑为:系统的登录页面是不应该暴露给普通用户的。
6. 系统中存在上传脚本
如果系统中存在上传文件功能,且不要登录,那么此项弱点一定会被扫描到,出现这个弱点,并不一定就代表系统中存在漏洞,扫描报告只是指出,系统中存在上传脚本,即存在上传功能的程序,而程序有没有问题,就要再次核实,扫描只是指出有这个功能而已。
针对上传功能,一定要检查上传文件的类型,不要让用户上传任意类型的文件。不要向用户暴露上传文件的路径,如果这两项同时满足,系统很容易被攻击。
7. 服务器信息泄露
7.1 什么是服务器信息泄露
服务器信息泄露是指在http请求中,服务器向客户端发送的内容包括了部分服务器的配置信息,比如系统使用的中间件的名称及版本号、web服务器的软件名称及版本号,服务器采用的相关编程技术等。
服务器应尽可能少的返回相关信息,见下图。
下图为访问北京移动,获取的服务器信息及web server信息。
下图为访问139邮箱返回的信息。
7.2 服务器信息泄露有什么危害
恶意攻击者可以通过服务器返回的相关信息进行非法操作,如当服务器返回了某软件的名称及版本号,此时,恶意攻击者可以通过搜索该软件存在的漏洞,从而进行恶意攻击。
7.3 如何发现服务器信息泄露
1. 进行工具扫描
2. 通过第三方软件进行查看http头信息。
3. Web开发必备工具:Firefox、web developer、firebug、httpwatch。
7.4 如何防止服务器信息泄露
对服务器的配置进行一一核查,将不必要的信息进行屏蔽。
8. 服务器目录泄露
8.1 什么是服务器目录泄露
服务器目录泄露是只没有限制用户对目录的访问,如果用户访问的目录没有默认文件可以展示,则将此目录下的所有文件以列表的方式进行展示,如下图。
http://www.apache.org/dist/httpd/binaries/
正常情况下,应该提示403错误。
8.2 服务器目录泄露有什么危害
1. 泄露服务器的文件目录结构。
2. 造成敏感文件被查看。
8.3 如何发现服务器目录泄露
查看服务器是否支持目录遍历。
8.4 如何防止服务器目录泄露
禁止服务器进行目录遍历。
增加默认403,404,500,503等页面
9. 服务器存在备份文件
此类弱点主要原因是在服务器上直接备份文件,如将index.jsp备份为index.jsp.bak,此类备份容易被工具或者认为进行试探,一旦存在此类文件,服务器会以文本方式进行展示,这样文件的内容就一览无余,恶意攻击者可以从文件内容中得到对他们有用的信息。
解决办法:不直接在服务器进行备份或者将备份的文件命名为比较复杂且不易猜测的名字。
10. 跨站请求伪造(CSRF)
10.1 什么是跨站请求伪造
CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。
CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。
10.2 跨站请求伪造有什么危害
跨站请求伪造是跨站脚本攻击的一种深入利用,它的危害性更大。如:给自己提升权限,增加管理员等。可以通过网上的一个案例说明这种攻击的危害:Bob在自己的电脑上刚刚查看完自己的银行A账户余额,然后比较无聊就跑到一个公开的BBS上灌水,当他看到一篇“银行A的内部照片”的帖子,很有兴趣的打开这个帖子想看看自己信任的银行A的内部图片是啥样子的,殊不知,这其实是一个attacker精心设计的骗局。在这个帖子中确实有几个图片,看上去真的像是银行A的照片,但是其中有个图片没显示出来,Bob以为是自己网速太慢,导致这个图片没有加载进来,也没在意。只是对这些并不是十分满意的照片摇摇头,就关了这个帖子。几天后,Bob猛然发现自己在银行A的账户上少了1000元,到底是怎么了?
设想一下,Alice编写了一个在Bob的银行站点上进行取款的form提交的链接,并将此链接作为图片tag。如果Bob的银行在cookie中保存他的授权信息,并且此cookie没有过期,那么当Bob的浏览器尝试装载图片时将提交这个取款form和他的cookie,这样在没经Bob同意的情况下便授权了这次事务。
10.3 跨站请求伪造的原理
下图简单阐述了CSRF攻击的思想:
从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤:
1.登录受信任网站A,并在本地生成Cookie。
2.在不登出A的情况下,访问危险网站B。
看到这里,你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证以下情况不会发生:
1.你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。
2.你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了......)
3.上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。
上面大概地讲了一下CSRF攻击的思想,下面我将用几个例子详细说说具体的CSRF攻击,这里我以一个银行转账的操作作为例子(仅仅是例子,真实的银行网站没这么傻:>)
示例1:
银行网站A,它以GET请求来完成银行转账的操作,如:http://www.mybank.com/Transfer.php?toBankId=11&money=1000
危险网站B,它里面有一段HTML的代码如下:
<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>
首先,你登录了银行网站A,然后访问危险网站B,噢,这时你会发现你的银行账户少了1000块......
为什么会这样呢?原因是银行网站A违反了HTTP规范,使用GET请求更新资源。在访问危险网站B的之前,你已经登录了银行网站A,而B中的<img>以GET的方式请求第三方资源(这里的第三方就是指银行网站了,原本这是一个合法的请求,但这里被不法分子利用了),所以你的浏览器会带上你的银行网站A的Cookie发出Get请求,去获取资源“http://www.mybank.com/Transfer.php?toBankId=11&money=1000”,结果银行网站服务器收到请求后,认为这是一个更新资源操作(转账操作),所以就立刻进行转账操作......
示例2:
为了杜绝上面的问题,银行决定改用POST请求完成转账操作。
银行网站A的WEB表单如下:
<form action="Transfer.php" method="POST">
<p>ToBankId: <input type="text" name="toBankId" /></p>
<p>Money: <input type="text" name="money" /></p>
<p><input type="submit" value="Transfer" /></p>
</form>
后台处理页面Transfer.php如下:
<?php
session_start();
if (isset($_REQUEST['toBankId'] && isset($_REQUEST['money']))
{
buy_stocks($_REQUEST['toBankId'], $_REQUEST['money']);
}
?>
危险网站B,仍然只是包含那句HTML代码:
<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>
和示例1中的操作一样,你首先登录了银行网站A,然后访问危险网站B,结果.....和示例1一样,你再次没了1000块~T_T,这次事故的原因是:银行后台使用了$_REQUEST去获取请求的数据,而$_REQUEST既可以获取GET请求的数据,也可以获取POST请求的数据,这就造成了在后台处理程序无法区分这到底是GET请求的数据还是POST请求的数据。在PHP中,可以使用$_GET和$_POST分别获取GET请求和POST请求的数据。在JAVA中,用于获取请求数据request一样存在不能区分GET请求数据和POST数据的问题。
示例3:
经过前面2个惨痛的教训,银行决定把获取请求数据的方法也改了,改用$_POST,只获取POST请求的数据,后台处理页面Transfer.php代码如下:
<?php
session_start();
if (isset($_POST['toBankId'] && isset($_POST['money']))
{
buy_stocks($_POST['toBankId'], $_POST['money']);
}
?>
然而,危险网站B与时俱进,它改了一下代码:
<html>
<head>
<script type="text/javascript">
function steal()
{
iframe = document.frames["steal"];
iframe.document.Submit("transfer");
}
</script>
</head>
<body onload="steal()">
<iframe name="steal" display="none">
<form method="POST" name="transfer" action="http://www.myBank.com/Transfer.php">
<input type="hidden" name="toBankId" value="11">
<input type="hidden" name="money" value="1000">
</form>
</iframe>
</body>
</html>
如果用户仍是继续上面的操作,很不幸,结果将会是再次不见1000块......因为这里危险网站B暗地里发送了POST请求到银行!
总结一下上面3个例子,CSRF主要的攻击模式基本上是以上的3种,其中以第1,2种最为严重,因为触发条件很简单,一个<img>就可以了,而第3种比较麻烦,需要使用JavaScript,所以使用的机会会比前面的少很多,但无论是哪种情况,只要触发了CSRF攻击,后果都有可能很严重。
理解上面的3种攻击模式,其实可以看出,CSRF攻击是源于WEB的隐式身份验证机制!WEB的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的!
10.4 如何防止跨站请求伪造
屏蔽get请求,服务器只接受post请求,对于get请求返回404页面或者错误提示。
10.5 参考资料
深入解析跨站请求伪造漏洞
http://www.05112.com/Article/200901/22100.html
浅谈CSRF攻击方式
http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html
Web安全测试之跨站请求伪造(CSRF)篇
http://blog.ixpub.net/html/46/1772146-374525.html
|