【安全】XSS安全漏洞与CSRF攻击

XSS攻击

XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java、 VBScript、ActiveX、 Flash 或者甚至是普通的HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。

攻击形态

xss有两种形态(网友总结):

  • 1、反射型

发出请求时,XSS代码出现在url中,作为输入提交到服务器端,服务器端解析后响应,XSS代码随响应内容一起传回给浏览器,最后浏览器解析执行XSS代码。这个过程像一次反射,所以叫反射型XSS。

  • 2、存储型

存储型XSS和反射型XSS的差别在于,提交的代码会存储在服务器端(数据库、内存、文件系统等),下次请求时目标页面时不用再提交XSS代码。

解决方法

先来看renren-fast项目是怎么解决这个问题的:

  • renren-fast

  1. #识别攻击脚本、并删掉对应可执行脚本的标签

    扫描二维码关注公众号,回复: 10491400 查看本文章
  2. HTMLFilter

  3. #全局过滤器,包装request

  4. XssFilter

  5. #包装request,重写request的几个重要方法,比如getParameter等

  6. XssHttpServletRequestWrapper

所以renren-fast项目的设计逻辑是加入一个全局过滤器,然后通过包装请求的request,重写request的getParameter、getHeader、getInputStream等方法,在这些方法里面都进行一遍过滤,从而去掉所有的攻击脚本。看看重要代码:

  • io.renren.common.xss.XssFilter

public class XssFilter implements Filter {


public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

throws IOException, ServletException {

XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper(

(HttpServletRequest) request);

chain.doFilter(xssRequest, response);

}


...

}
 
  • io.renren.common.xss.XssHttpServletRequestWrapper

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {


@Override

public String getParameter(String name) {

String value = super.getParameter(xssEncode(name));

if (StringUtils.isNotBlank(value)) {

value = xssEncode(value);

}

return value;

}

...

}

可以看到上面的xssEncode就是进行过滤脚本的方法;xssEncode方法代码如下:

private String xssEncode(String input) {

return htmlFilter.filter(input);

}

CSRF

全称:Cross-site request forgery,跨站请求伪造。原理是:通过伪装成受信任用户的请求来攻击受信任的网站。

如何伪装?如何才算攻击?

生活中其实我们不缺这种例子,比如说我们经常接收到一些来历不明的垃圾短信,短信内容里面有个url链接,有些人手贱点开了链接,然后就发现钱不见了!!

我们从技术角度来复原一下这个过程,首先设定一些基础:

  • 垃圾短信里的链接(垃圾网):http://www.lajiwang.com/pianqian

  • 存了钱的网站(存钱网):http://www.cunqianwang.com/

然后用户动作是:点开了垃圾网的链接,但是存钱网里账户的钱不见了。既然是自己账户的钱不见了,所以这里其实有个前提:用户已经登录了存钱网!所以准确来说用户的动作是这样的:点开了垃圾网的链接,但是之前登录过的存钱网里账户的钱不见了!

两个网站毫无关联,为啥会造成这个让人意想不到的后果呢?

其实呀,垃圾网的人为了达到攻击的目的,偷偷在网页上嵌入了存钱网的链接,所以打开垃圾网时候顺便也触发了存钱网的转账的链接,整体逻辑如下:

  • 1、用户登录成功存钱网,于是浏览器中产生了网站cookie

  • 2、用户在没有退出存钱网的情况下,访问了垃圾网

  • 3、垃圾网要求访问存钱网的转账url,转账url带上存钱网的cookie去访问服务器

  • 4、存钱网服务器验证转账url确认是用户在转账,转账成功!

说到这里,你发现漏洞在哪里没有?大家都知道cookie代表用户身份,每次发起请求,请求头里都会附上用户的cookie信息,既然cookie是存在浏览器的,我偷不到你的cookie,那么我就让你在不知道到的情况下让你自己去操作。

举个例子:假如一家银行转账操作的URL地址如下:

  1. http://www.cunqianwang.com/zhuanzhang?account=A&for=B&amount=500

那么,一个垃圾网中可以放置如下代码

  1. <img src="http://www.cunqianwang.com/zhuanzhang?account=A&for=B&amount=500"> 

好了,原理和攻击手段我们都懂了,那么我们来说说几种常见的预防手段:

1、检查referer字段

HTTP头中有一个Referer字段,这个字段是用来标明请求来源于哪一个网址。当网站A去访问网站B的资源时候,链接上的请求头上就会有Referer字段。注意是在不同域名下才有。

我随意打开hao123.com的首页,一些图片不是放在hao123.com域名下的,所以会在header中带上Referer字段表示请求源是hao123.com。

那么服务器可以通过判断Referer字段来判断请求的来源。所以在垃圾网站里访问存钱网,Referer的值就是垃圾网的域名,就能判断是不是合法的操作啦。

java代码里获取Referer字段值代码是:

  1. String referer = request.getHeader("Referer");

这种方法简单易行,但也有其局限性。http协议无法保证来访的浏览器的具体实现,可以通过篡改Referer字段的方式来进行攻击,所以就要看你用的浏览器高级不高级了,如果你用的浏览刚好是骗子开发的浏览器,嘿嘿~~

2、Token 验证

既然我们要判定用户行为的合法性,那么我就给用户颁发一个合法token,除了带上cookie,还得带上token才行,token在前一个步骤中获取。

逻辑如下:

  • 服务器发送给客户端一个token;

  • 客户端提交的表单中带着这个token。

  • 如果这个 token 不合法,那么服务器拒绝这个请求。

3、添加图片验证码、短信验证等

重要步骤添加验证码认证后才能操作。

——————————————————————————————————————

参考文章:

1、https://baike.baidu.com/item/XSS%E6%94%BB%E5%87%BB/954065?fr=aladdin

2、java思维导图

发布了173 篇原创文章 · 获赞 326 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/William0318/article/details/104036822