今天学习了一些常见的Web 攻击手段,如 xss攻击、CSRF 攻击、SQ L 注入攻击、DDos攻击等。 xss攻击、CSRF 攻击、SQL 注入攻击等这类攻击手段相对来说比较容易防范,对症下药即可。对于企业来说,更多是需要从开发流程上来予以保障,以免因人为的疏忽而造成损失。而对于 DDos 攻击来说,攻击手段多样,产生的影响及危害巨大,对它的防范也是一 个复杂的系统工程,需要持续性地组织防御演练,做好应急预案,并保持有效的监控。下面我将一一去介绍:
1.XSS(跨站脚本攻击 Cross Site Scripting,为避免跟CSS重复,命名XSS)
是指攻击者在网页中嵌入恶意脚本程序执行,当用户打开网页时,执行脚本程序,获取用户的cookie、用户名和密码,下载病毒,甚至获取admin权限。是最常见的web攻击手段之一。
他的原理是这样的,比如在网页中有一个表单,名称为nick,用来向服务端提交网站用户信息。
<input type= "text" name= "nick" value= "xiaomao ">
表单 nick 的内容来 自用户的输入,当用户输入的不是一 个正常的昵称字符串,而是 "/><script>alert("haha ")</script><!- 时,由于某种原因,如 nick 服务端校验不通过,服务端重定向回这个页面,并且带上之前用户输入的 nick 参数,此时页面则变成下面的内容:
<input type= "text" name= "nick" value= ""/><script>alert ("haha") </script> < !- " />
攻击者可以对该URL采用URLEncode, 如图3-2所示,以迷惑用户,让它看起来像是一个正常的推广链接,并且以邮件群发或者其他形式进行推广,一旦用户点击,脚本将在客户端执行,对用户造成危害。
还有一 种场景,用户在表单上输入一段数据后,提交给服务端进行持久化,其他页面需要从服务端将数据取出来展示。
解决方案:
xss之所以会发生,是因为用户输入的数据变成了代码。因此,我们需要对用户输入的数,据进行HTML转义处理,将其中的 “尖括号”、“单引号”、“引号” 之类的特殊字符进行转义编码.
进行HTML转移处理。把将括号,单双引号特殊字符转义。
2.CRSF攻击(cross site request forgery 跨站脚本请求伪造)
CSRF攻击的全称是跨站请求伪造(cross site request forgery), 是一 种对网站的恶意利用,尽管听起来跟 xss跨站脚本攻击有点相似,但事实上 CSRF 与 xss差别很大,xss利用的是站点内的信任用户,而CSRF则是通过伪装来自受信任用户的请求来利用受信任的网站。你可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义向第三方网站发送恶意请求。CRSF能做的事情包括利用你的身份发邮件、发短信、进行交易转账等,甚至盗取你的账号。
-
CRSF攻击原理
如图,在恶意站点B冒充用户C去请求站点A,就可以做一些发送邮件,短信,支付,消息等操作。
受害者在满足了以下两点,登录站点B,攻击者就能发起CSRF攻击了:
• 登录受信任站点A,并在本地生成cookie;
• 在不登出站点A(清除站点A的cookie)的情况下,访问恶意站点B
举个例子:
假设某银行网站A以GET请求来发起转账操作,转账的地址为www.xxx.com/transfer.do?accountNum=10001&money=10000, 参数accountNum表示转账的目的账户,参数money表示转账金额。
而某大型论坛B上,一个恶意用户上传了一张图片,而图片的地址栏中填的并不是图片的地址,而是前面所说的转账地址:
<img src="http://www.xxx.com/transfer.do?accountNum=l0001&money=10000">
当你登录网站A后,没有及时登出,这时你访间了论坛B,不幸的事情发生了,你会发现你的账户里面少了10000块……
为什么会这样呢,在你登录银行A时,你的浏览器端会生成银行A的cookie,而当你访问论坛B的时候,页面上的<img>标签需要浏览器发起一个新的HTTP请求,以获得图片资源, 浏览器发起请求时,请求的却是银行A的转账地址www.xxx.com/transfer.do?accountNum=
I 000 I &money= I 0000, 并目会带上银行A的cookie信息,结果银行的服务器收到这个请求后,会认为是你发起的一次转账橾作,因此你的账户里边便少了10000块。
俨然,绝大多数网站都不会使用GET请求来进行数据更新,因此,攻击者也需要改变思路,与时俱进。
假设银行将其转账方式改成POST提交,而论坛B恰好又存在一个xss漏洞,恶意用户在它的页而上插入如下代码:
如果你此时恰好登录了银行 A , 且没有登出,当你打开上述页面后,脚本会将表单 aaa 提交,把 accountN um 和m oney 参数传递给银行的转账地址 www .xxx.com /transfer.do, 同样的,银行以为是你发起的一 次转账,会从你的账户中扣除 10000 块。
当然,以上只是举例,正常来说银行的交易付款会有 USB key、验证码、登录密码和支付密码等一 系列屏障,流程比上述流程复杂得多,因此安全系数也高得多。
解决方案:
(1)将 cookie 设置为HttpOnly
CRSF 攻击很大程度上是利用了浏览器的 cookie, 为了防止站内的 xss漏洞盗取 cookie,需要在 cookie 中设置 "HttpOnly" 属性,这样通过程序(如JavaScript脚本、Applet等)就无法读取到 cookie 信息,避免了攻击者伪造 cookie 的情况出现。
在Java 的Servlet的API中设置cookie 为HttpOnly 的代码如下:
response. setHeader ("Set-Cookie", "cookiename = cookievalue; HttpOnly");
(2) 增加token
CSRF 攻击之所以能够成功,是因为攻击者可以伪造用户的请求,该请求中所有的用户验证信息都存在于 cookie 中,因此攻击者可以在不知道用户验证信息的情况下直接利用用户的cookie 来通过安全验证。由此可知,抵御 CSRF 攻击的关键在于:在请求中放入攻击者所不能伪造的信息,并且该信息不存在于 cookie 之中。鉴千此,系统开发人员可以在HTTP 请求中以参数的形式加入一 个随机产生的token, 并在服务端进行 token 校验,如果请求中没有 token 或者token 内容不正确,则认为是CSRF 攻击而拒绝该请求。
在session中添加token的实现代码:(3)通过Referer识别(不常用)
根据HTTP协议,在HTTP头中有一个字段叫Referer,它记录了该HTTP请求的来源地址。在通常情况下,访问一个安全受限的页面的请求都来自千同一个网站。比如某银行的转账是通过用户访问http://www.xxx.com/transfer.do页面完成的,用户必须先登录www.xxx.com,然后通过单击页面上的提交按钮来触发转账事件。当用户提交请求时,该转账请求的Referer值就会是提交按钮所在页面的URL(本例为www.xxx.com/transfer.do)。如果攻击者要对银行网站实施CSRF攻击,他只能在其他网站构造请求,当用户通过其他网站发送请求到银行时,该请求的Referer的值是其他网站的地址,而不是银行转账页面的地址。因此,要防御CSRF攻击,银行网站只需要对于每一个转账请求验证其Referer值即可,如果是以www.xxx.com域名开头的地址,则说明该请求是来自银行网站自己的请求,是合法的;如果Referer是其他网站,就有可能是CSRF攻击,则拒绝该请求。
取得HTTP请求Referer:
String referer = request.getHeader("Referer")
3.SOL注入攻击(危害极大)
所谓SQL注入,就是通过把SQL命令伪装成正常的HTTP请求参数,传递到服务端,欺骗服务器最终执行恶意的SQL命令,达到入侵目的。攻击者可以利用SQL注入漏洞,查询非授权信息,修改数据库服务器的数据,改变表结构,甚至是获取服务器root权限。
比如在登录的input中,把密码设置成:
'or 1=1';
那么在执行的时候就会变成:
select* from hhuser where nick='zhangsan'and passwords = '' or 'l'='l'
可以看到,这条语句一定能查询出来的,不管密码对不对,都满足后面的Or 条件。
如果改成这样呢?在密码框输入';drop table aaa;--
select * from hhuser where nick = 'zhangsan'and passwords =''; drop table aaa--'
就会造成更严重的后果,数据库表被删除了。
解决方案
1.使用预编译语句
预编译语句PreparedStatement是java.sql中的一个接口,继承自Statement接口。通过Statement对象执行SQL语句时,需要将SQL语句发送给DBMS,由DBMS先进行编译后再执行。而预编译语句和Statement不同,在创建PreparedStatement对象时就指定了SQL语句,该语句立即发送给DBMS进行编译,当该编译语句需要被执行时,DBMS直接运行编译后的SQL语句,而不需要像其他SQL语句那样先将其编译。
引发SQL注入的根本原因是恶意用户将SQL指令伪装成参数传递到后端数据库执行。作为一种更为安全的动态字符串的构建方法,预编译语句使用参数占位符来替代需要动态传入的参数,这样攻击者无法改变SQL语句的结构,SQL语句的语义不会发生改变,即便用户传入类似千前面or'l'='l这样的字符串,数据库也会将其作为普通的字符串来处理。
2.使用ORM框架
常见的ORM框架IBATIS、Hibernate等都支持相应的关键字或特殊符号转义。
通过#符号配置的变量,iBATIS能够对输入变量的一些关键字进行转义,防止SQ L 注入攻击。
3.避免免密码明文存放
采用MD5加盐加密后持久化密码数据。
- 文件上传的漏洞
文件上传攻击指的是恶意攻击者利用一些站点没有对文件的类型做很好的校验,上传了可执行的文件或者脚本,并且通过脚本获得服务器上相应的权利,或者是通过诱导外部用户访问、下载上传的病毒或木马文件,达到攻击的目的。
为了防范用户上传恶意的可执行文件和脚本,以及将文件上传服务器当做免费的文件存储服务器使用,我们需要对上传的文件类型进行白名单(非黑名单,这点非常重要)校验,并且限制上传文件的大小,上传的文件需要进行重新命名,使攻击者无法猜测到上传文件的访问路径。
对千上传的文件来说,不能简单地通过后缀名称来判断文件的类型,因为恶意攻击可以将可执行文件的后缀名称改成图片或者其他后缀类型,诱导用户执行。因此,判断文件类型需要使用更安全的方式。
很多类型的文件,起始的几个宁节内容是固定的,因此,根据这几个字节的内容,就可以确定文件类型,这几个字节也被称为魔数6(magic number)。
在后台中,我们可以通过魔数来判断文件的类型
不同类型的文件对应不同的文件头,FileType中包含了常用的文件类型对应的文件头的十六进制编码。
读取文件头,判断文件类型:
/**
*读取文件头
*/
privates七aticString getFileHeader(String filePath) throws IOException
//这里需要注意的是,每个文件的魔数的长度都不相同,因此需要使用startwith
byte db = new byte [ 2 8 ] ;
InputStrearn inputStream = null;
inputstream=new FileinputStream(filePath); inputStream.read(b, 0, 28);
inputstream.close();
return bytes2hex(b);
**
*判断文件类型
*/
public static FileTypegetType(String filePath)throws IOException {
String fileHead = getFileHeader(filePath);
if (fileHead == null || fileHead.length () == 0) {
return null;
}
}
对一 个文件的前 28 个字节进行读取,并将读取的内容转换成为十六进制,与前面 FileType中枚举的文件头进行对比,判断文件的类型。
对于图片类型的文件,可以在上传后,对图片进行相应的缩放,破坏恶意用户上传的二进制可执行文件的结构,来避免恶意代码执行。
解决方案
1.后台,可以使用imagemagick 开发工具包
2.前端可以使用前端框架进行限制上传的文件的格式和校验。
待续: DDos攻击
https://www.jianshu.com/p/fd871bad94ad
整理不易,喜欢请点个赞