安全攻击与防护策略

[b]一、跨站脚本攻击(XSS)[/b]

跨站脚本攻击,即Cross Site Script Execution(通常简写为XSS)是指攻击者利用网站程序对用户输入过滤不足,输入可以显示在页面上,对其他用户造成影响的HTML代码,从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。

(1)跨站脚本攻击分类

1、反射型XSS

反射型跨站脚本漏洞是最基本的web漏洞,当web客户端提供数据时,就会出现这种漏洞,常见于HTTP查询参数(例如,HTML表单提交),服务端脚本在没有正确过滤请求时,就立即解析并展示页面结果给用户。因为html文档是流式结构并且混合了控制状态,格式化,真实内容,结果页面中包含的任何未经验证的用户提交数据,如果没有正确的进行html编码,都有可能导致标签注入。一个典型例子是一个网站搜索引擎:如果搜索了一个字符串,这个搜索字符串通常会在搜索页再显示一次,告诉用户搜索了什么。如果响应没有正确忽略或者拒绝html控制字符串,跨站脚本风险随之而来。

2、存储型XSS

存储型XSS漏洞是一种更有破坏性的跨站脚本缺陷的变种:当攻击者提供的数据保存到了服务端,然后永久的显示在“正常”页面,并且其他用户在浏览器是可以看到,如果这些数据没有经过正确的html编码,就会发生这种攻击。一个典型的例子就是在线留言板,允许用户发布html格式的信息,可以让其他用户看到。

(2)跨站脚本攻击防护措施

1、采用Filter技术,对所有参数都进行过滤,处理方案为:1. 含有html标签做转义。2. 含有敏感的html脚本,直接处理掉

2、对用户输入的特殊符号进行HTML转义后再输出,将 < > & ‘ “ 在输出前分别转义为 < > & ' $quot;

[b] 二、SQL注入[/b]

SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。

(1)SQL注入攻击实例

比如在一个登录界面,要求输入用户名和密码:
可以这样输入实现免帐号登录:
用户名: ‘or 1 = 1 –
密 码:
点登陆,如若没有做特殊处理,那么这个非法用户就很得意的登陆进去了.(当然现在的有些语言的数据库API已经处理了这些问题)
这是为什么呢? 下面我们分析一下:
从理论上说,后台认证程序中会有如下的SQL语句:

String sql = "select * from user_table where username=
' "+userName+" ' and password=' "+password+" '";
当输入了上面的用户名和密码,上面的SQL语句变成:
SELECT * FROM user_table WHERE username='’or 1 = 1 -- and password='’
"""
分析SQL语句:
条件后面username=”or 1=1 用户名等于 ” 或1=1 那么这个条件一定会成功;

然后后面加两个-,这意味着注释,它将后面的语句注释,让他们不起作用,这样语句永远都能正确执行,用户轻易骗过系统,获取合法身份。
这还是比较温柔的,如果是执行
SELECT * FROM user_table WHERE
username='' ;DROP DATABASE (DB Name) --' and password=''
其后果可想而知…"""

(2)防止sql注入措施

1、检查变量数据类型和格式

如果你的SQL语句是类似where id={$id}这种形式,数据库里所有的id都是数字,那么就应该在SQL被执行前,检查确保变量id是int类型;如果是接受邮箱,那就应该检查并严格确保变量一定是邮箱的格式,其他的类型比如日期、时间等也是一个道理。总结起来:只要是有固定格式的变量,在SQL语句执行前,应该严格按照固定格式去检查,确保变量是我们预想的格式,这样很大程度上可以避免SQL注入攻击。

比如,我们前面接受username参数例子中,我们的产品设计应该是在用户注册的一开始,就有一个用户名的规则,比如5-20个字符,只能由大小写字母、数字以及一些安全的符号组成,不包含特殊字符。此时我们应该有一个check_username的函数来进行统一的检查。不过,仍然有很多例外情况并不能应用到这一准则,比如文章发布系统,评论系统等必须要允许用户提交任意字符串的场景,这就需要采用过滤等其他方案了。

2、过滤特殊符号

对于无法确定固定格式的变量,一定要进行特殊符号过滤或转义处理。

3、绑定变量,使用预编译语句

MySQL的mysqli驱动提供了预编译语句的支持,不同的程序语言,都分别有使用预编译语句的方法。实际上,绑定变量使用预编译语句是预防SQL注入的最佳方式,使用预编译的SQL语句语义不会发生改变,在SQL语句中,变量用问号?表示,黑客即使本事再大,也无法改变SQL语句的结构.

[b]三、CSRF(跨站请求伪造)[/b]

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

(1)CSRF原理

下面一张图简单阐述了CSRF的原理


[img]http://dl2.iteye.com/upload/attachment/0130/7096/b0873589-5d40-30a2-8a13-026be1d9542f.jpg[/img]


从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成以下两个步骤:
登录受信任网站A,并在本地生成Cookie。
在不登出A的情况下,访问危险网站B。
看到这里,你也许会问:“如果我不满足以上两个条件中的一个,我就不会受到CSRF攻击”。是滴,确实如此,但是你不能保证以下情况不会发生:
你不能保证你登录了一个网站之后,不再打开一个tab页面并访问其它的网站(非法网站)。
你不能保证你关闭浏览器之后,你本地的Cookie立刻过期,你上次的会话已经结束。
上述中所谓的攻击网站,可能就是一个钓鱼网站或者非法网站。

(2)CSRF防护措施

[b]检查Referer字段[/b]

HTTP头中有一个Referer字段,这个字段用以标明请求来源于哪个地址。在处理敏感数据请求时,通常来说,Referer字段应和请求的地址位于同一域名下。以银行操作为例,Referer字段地址通常应该是转账按钮所在的网页地址,应该也位于ww.examplebank.com之下。而如果是CSRF攻击传来的请求,Referer字段会是包含恶意网址的地址,不会位于www.examplebank.com之下,这时候服务器就能识别出恶意的访问。

这种办法简单易行,工作量低,仅需要在关键访问处增加一步校验。但这种办法也有其局限性,因其完全依赖浏览器发送正确的Referer字段。虽然http协议对此字段的内容有明确的规定,但并无法保证来访的浏览器的具体实现,亦无法保证浏览器没有安全漏洞影响到此字段。并且也存在攻击者攻击某些浏览器,篡改其Referer字段的可能。

[b]添加校验token[/b]

由于CSRF的本质在于攻击者欺骗用户去访问自己设置的地址,所以如果要求在访问敏感数据请求时,要求用户浏览器提供不保存在cookie中,并且攻击者无法伪造的数据作为校验,那么攻击者就无法再执行CSRF攻击。这种数据通常是表单中的一个数据项。服务器将其生成并附加在表单中,其内容是一个伪乱数。当客户端通过表单提交请求时,这个伪乱数也一并提交上去以供校验。正常的访问时,客户端浏览器能够正确得到并传回这个伪乱数,而通过CSRF传来的欺骗性攻击中,攻击者无从事先得知这个伪乱数的值,服务器端就会因为校验token的值为空或者错误,拒绝这个可疑请求

[b]四、Tomcat版本号泄露[/b]

Tomcat报错页面泄漏Apache Tomcat/7.0.52相关版本号信息,是攻击者攻击的途径之一。因此实际当中建议去掉版本号信息。

防范措施:

<!-- error servlet 处理 -->
<servlet>
<servlet-name>ErrorServlet</servlet-name>
<servlet-class>com.commons.service.util.web.ErrorServlet</servlet-class>
<init-param>
<param-name>beanName</param-name>
<param-value>errorUrl</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>ErrorServlet</servlet-name>
<url-pattern>/errorServlet</url-pattern>
</servlet-mapping>

<!-- 出错页面定义 -->
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/errorServlet</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/errorServlet</location>
</error-page>
<error-page>
<error-code>501</error-code>
<location>/errorServlet</location>
</error-page>
<error-page>
<error-code>502</error-code>
<location>/errorServlet</location>
</error-page>
<error-page>
<error-code>503</error-code>
<location>/errorServlet</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/errorServlet</location>
</error-page>
<error-page>
<error-code>400</error-code>
<location>/errorServlet</location>
</error-page>
<error-page>
<error-code>401</error-code>
<location>/errorServlet</location>
</error-page>
<error-page>
<error-code>402</error-code>
<location>/errorServlet</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/errorServlet</location>
</error-page>
<error-page>
<error-code>407</error-code>
<location>/errorServlet</location>
</error-page>
<error-page>
<error-code>415</error-code>
<location>/errorServlet</location>
</error-page>


[b]五、重放攻击[/b]

重放攻击的基本原理就是把以前截获到的数据原封不动地重新发送给接收方。很多时候,网络上传输的数据是加密过的,此时攻击者无法得到数据的准确意义。但如果他知道这些数据的作用,就可以在不知道数据内容的情况下通过再次发送这些数据达到愚弄接收端的目的。例如,有的系统会将鉴别信息进行简单加密后进行传输,这时攻击者虽然无法截获密码,但他们却可以首先截取加密后的口令然后将其重放,从而利用这种方式进行有效的攻击。

防御措施:

1、加随机数:该方法优点是认证双方不需要时间同步,双方记住使用过的随机数,如发现报文中有以前使用过的随机数,就认为是重放攻击。

2、加时间戳:该方法优点是不用额外保存其他信息。缺点是认证双方需要准确的时间同步,同步越好,受攻击的可能性就越小。但当系统很庞大,跨越的区域较广时,要做到精确的时间同步并不是很容易。

[b]六、只允许get,post这2个请求[/b]

解决措施:
在web.xml中加入如下代码:

<!-- 去掉多余的请求方式 -->
<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>HEAD</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
<http-method>PATCH</http-method>
</web-resource-collection>
<auth-constraint>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值