一个反射型XSS例子的解析

标签: 反射 xss 解析 | 发表时间:2013-12-17 23:43 | 作者:kkdelta
出处:http://blog.csdn.net
我们在访问一个网页的时候,在URL后面加上参数,服务器根据请求的参数值构造不同的HTML返回。
如http://localhost:8080/prjWebSec/xss/reflectedXSS.jsp?param=value...
上例中的value可能出现在返回的HTML(可能是JS,HTML某元素的内容或者属性)中,
如果将value改成可以在浏览器中被解释执行的东西,就形成了反射型XSS.
有人会问,我怎么可能自己去把value改成可以执行的恶意代码呢?这不是自己坑自己吗.
但是一种情况是别人可能修改这个value值,然后将这个恶意的URL发送给你,或者别人,当URL地址被打开时,
特有的恶意代码参数被HTML解析,执行.它的特点是非持久化,必须用户点击带有特定参数的链接才能引起.

下面来看一个简单的例子:

utilits.js:
	function writeToDom(str){
		document.writeln(str);
	}
	function writelnToDom(str){
		document.writeln(str + "<br>");
	}
reflectedXSS.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="org.apache.commons.lang.StringEscapeUtils"%>
<%@ page import="java.net.URLDecoder,java.net.URLEncoder"%>
<%@ page import="org.owasp.esapi.ESAPI"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>test XSS</title>
<script type="text/javascript" src="../js/utilits.js"></script>
</head>
<%
	String param = request.getParameter("param");
	System.out.println("original " + param);
%>
<script>
	var scriptVar='<%=param%>';
	writelnToDom("original: " + scriptVar);	
</script>
<body>
</body>
</html>
当用户通过URL http://localhost:8080/prjWebSec/xss/reflectedXSS.jsp?param=value访问的时候,
浏览器输出original: value
但是如果URL改成 http://localhost:8080/prjWebSec/xss/reflectedXSS.jsp?param=value';alert('x')//
浏览器会先alert,然后输出original: value.
查看浏览器的源码可以看到:var scriptVar='value';alert('x')//';
当value';alert('x')//被返回给浏览器的时候var scriptVar='<%=param%>';变成了
var scriptVar='value';alert('x')//';
这就是一个简单的反射型XSS实例.
下面我们来看怎么防止这种XSS.commons-lang和OWASP的ESAPI都提供了工具类。

<%
	String param = request.getParameter("param");
	System.out.println("original " + param);
	String secparam = StringEscapeUtils.escapeJavaScript(request.getParameter("param"));
	System.out.println("StringEscapeUtils " + secparam);
	String owaspparam = ESAPI.encoder().encodeForJavaScript(request.getParameter("param")); 
	System.out.println("OWASP " + owaspparam);
	
	out.write("server side output -------------------------------------------------------  ");
	out.write("<br>original: " + param);
	out.write("<br>StringEscapeUtils: " + secparam);
	out.write("<br>OWASP: " + owaspparam);
%>
<script>
	writelnToDom("<br> client side output---------------------------------------------");
	var scriptVar='<%=param%>';
	writelnToDom("original: " + scriptVar);
	var secVar='<%=secparam%>';
	writelnToDom('StringEscapeUtils:' + secVar);
	
	var owaspparam='<%=owaspparam%>';
	writelnToDom("OWASP: " + owaspparam);
</script>
以这个URL来测试
http://localhost:8080/prjWebSec/xss/reflectedXSS.jsp?param=value中文';alert('x')//<>
system.out的输出为:
original value中文';alert('x')//<>
StringEscapeUtils value\u4E2D\u6587\';alert(\'x\')//<>
OWASP value\u4E2D\u6587\x27\x3Balert\x28\x27x\x27\x29\x2F\x2F\x3C\x3E
浏览器会alert一次,同时输出下面的内容
server side output -------------------------------------------------------
original: value中文';alert('x')//<>
StringEscapeUtils: value\u4E2D\u6587\';alert(\'x\')//<>
OWASP: value\u4E2D\u6587\x27\x3Balert\x28\x27x\x27\x29\x2F\x2F\x3C\x3E
client side output---------------------------------------------
original: value中文
StringEscapeUtils:value中文';alert('x')//<>
OWASP: value中文';alert('x')//<>
StringEscapeUtils.escapeJavaScript会对单引号'和双引号"前面加上转意符(\),对宽字节字符
进行unicode编码(\u+十六进制).
ESAPI.encoder().encodeForJavaScript会对所有非数字和非英文字符的字符进行编码,对宽字节字符
进行unicode编码,对其他字符进行\x+十六进制编码。
浏览器执行JavaScript的时候会解释转意和解码成字符.相当于自动调用了JavaScripte的unescape方法.
通过escapeJavaScript和encodeForJavaScript可以避免输出到JavaScript的内容被当做JavaScript执行。

那下面这个URL会发生什么事情呢?    
http://localhost:8080/prjWebSec/xss/reflectedXSS.jsp?param=1中文';alert('x')//<img src=@ onError="javascript:alert('error')">
会弹出一个alert('x')和3次alert('error'),同时DOM里被添加了3个
<img onerror="javascript:alert('error')" src="@">
这是什么原因造成的呢?alert('x')的执行还是因为没有对Javascript的元素进行编码.
另外3个alert('error')是因为html内容没有经过html编码,在DOM里插入了3个img元素,取不到src指定的
图片,从而触发了onerror事件.
解决的方法是如果要将返回数据做为HTML节点的内容,一定要保证内容被真正的当做数据来解释,
而不要被解释成html元素。
StringEscapeUtils.escapeHtml和ESAPI.encoder().encodeForHTML可以帮助我们完成这个功能.
下面的代码既保证了不被当做Javascript脚本,也保证了不被解释成HTML元素.
<%
String doubleSecparam = StringEscapeUtils.escapeJavaScript(
StringEscapeUtils.escapeHtml(request.getParameter("param")));

String doubleOwasp = ESAPI.encoder().encodeForJavaScript(
ESAPI.encoder().encodeForHTML(request.getParameter("param")));
%>
<script>
	var doubleScriptVar='<%=doubleSecparam%>';
	writelnToDom("doubleSecparam StringEscapeUtils: " + doubleScriptVar);
	var doubleOwasp='<%=doubleOwasp%>';
	writelnToDom("Double OWASP: " + doubleOwasp);	
</script>

查看浏览器的源码,我们发现html元素会被编码成html entity

var doubleScriptVar='1中文\';alert(\'x\')//<img 
src=@ onError="javascript:alert(\'error\')">';

var doubleOwasp='1\x26\x23x4e2d\x3B\x26\x23x6587\x3B\x26\x23x27\x3B\x26\x23x3b\x3Balert\x26
\x23x28\x3B\x26\x23x27\x3Bx\x26\x23x27\x3B\x26\x23x29\x3B\x26\x23x2f\x3B\x26\x23x2f\x3B
\x26lt\x3Bimg\x20src\x26\x23x3d\x3B\x26\x23x40\x3B\x20onError\x26\x23x3d\x3B
\x26quot\x3Bjavascript\x26\x23x3a\x3Balert\x26\x23x28\x3B\x26\x23x27\x3Berror
\x26\x23x27\x3B\x26\x23x29\x3B\x26quot\x3B\x26gt\x3B';
当然,现实过程中,很少有网站有如此明显的xss漏洞.这里只是给大家示范了一下反射型xss的原理,现实中的漏洞虽然五花八门,但是本质是不变的.

作者:kkdelta 发表于2013-12-17 15:43:23 原文链接
阅读:0 评论:0 查看评论

相关 [反射 xss 解析] 推荐:

一个反射型XSS例子的解析

- - CSDN博客推荐文章
我们在访问一个网页的时候,在URL后面加上参数,服务器根据请求的参数值构造不同的HTML返回. 如http://localhost:8080/prjWebSec/xss/reflectedXSS.jsp?param=value. 上例中的value可能出现在返回的HTML(可能是JS,HTML某元素的内容或者属性)中,.

Chrome 是怎么过滤反射型 XSS 的呢?

- - 知乎每日精选
首先要说明的是 它是webkit的一个模块,而非chrome,所以Safari和360安全浏览器极速模式等webkit内核的浏览器都有XSS过滤功能. 通过模糊匹配 输入参数(GET query| POST form data| Location fragment ) 与 dom树,如果匹配中的数据中包含跨站脚本则不在输出到上下文DOM树中.另外,匹配的规则跟CSP没有什么关系,最多是有参考,CSP这种规范类的东西更新速度太慢跟不上现实问题的步伐.

利用反射型XSS二次注入绕过CSP form-action限制

- - WooYun知识库
翻译: SecurityToolkit. CSP(Content-Security-Policy)是为了缓解XSS而存在的一种策略, 开发者可以设置一些规则来限制页面可以加载的内容.那文本中所说的form-action又是干啥的呢?用他可以限制form标签"action"属性的指向页面, 这样可以防止攻击者通过XSS修改表单的"action"属性,偷取用户的一些隐私信息..

深掘XSS漏洞场景之XSS Rootkit

- jyf1987 - 80sec
深掘XSS漏洞场景之XSS Rootkit[完整修订版]. 众所周知XSS漏洞的风险定义一直比较模糊,XSS漏洞属于高危漏洞还是低风险漏洞一直以来都有所争议. XSS漏洞类型主要分为持久型和非持久型两种:. 非持久型XSS漏洞一般存在于URL参数中,需要访问黑客构造好的特定URL才能触发漏洞. 持久型XSS漏洞一般存在于富文本等交互功能,如发帖留言等,黑客使用的XSS内容经正常功能进入数据库持久保存.

XSS 探索 - big-brother

- - 博客园_首页
正常的页面被渗出了攻击者的js脚本,这些脚本可以非法地获取用户信息,然后将信息发送到attacked的服务端. XSS是需要充分利用输出环境来构造攻击脚本的. 非法获取用户cookie、ip等内容. 劫持浏览器,形成DDOS攻击. Reflected XSS:可以理解为参数型XSS攻击,攻击的切入点是url后面的参数.

前端xss攻击

- - SegmentFault 最新的文章
实习的时候在项目中有接触过关于xss攻击的内容,并且使用了项目组中推荐的一些常用的防xss攻击的方法对项目进行了防攻击的完善. 但一直没有时间深入了解这东西,在此,做一个简单的梳理. xss跨站脚本攻击(Cross Site Scripting),是一种经常出现在web应用中的计算机安全漏洞,它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入的恶意html代码会被执行,从而达到恶意用户的特殊目的.

百度知道XSS漏洞

- - 博客园_首页
事情的起因是我一同学在百度知道上看到一个很奇怪的,正文带有连接的提问( 这里),正常来说,这种情况是不可能出现的. 我条件反射的想到了:XSS漏洞. 通过查看源代码,我马上发现了问题的根源:未结束的标签.
帮我写一个能提取

pentesterlab xss漏洞分析

- - JavaScript - Web前端 - ITeye博客
pentesterlab简介. pentesterlab官方定义自己是一个简单又十分有效学习渗透测试的演练平台. pentesterlab环境搭建. 官方提供了一个基于debian6的镜像,官网下载镜像,使用vmware建立一个虚拟机,启动即可. ps:官方文档建议做一个host绑定,方便后面使用.

XSS攻击及防御

- - BlogJava-qileilove
XSS又称CSS,全称Cross SiteScript,跨站脚本攻击,是Web程序中常见的漏洞,XSS属于被动式且用于客户端的攻击方式,所以容易被忽略其危害性. 其原理是攻击者向有XSS漏洞的网站中输入(传入)恶意的HTML代码,当其它用户浏览该网站时,这段HTML代码会自动执行,从而达到攻击的目的.

XSS攻击技术详解

- - BlogJava-qileilove
  XSS攻击:跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆. web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中. 比如这些代码包括HTML代码和客户端脚本. 攻击者利用XSS漏洞旁路掉访问控制--例如同源策略(same origin policy).