怎样过滤跨站恶意脚本攻击(XSS)
什么是XSS?
XSS(Cross Site Scripting),即跨站脚本攻击,是一种常见于web
application中的计算机安全漏洞。XSS通过在用户端注入恶意的可运行脚本,若服务器端对用户输入不进行处理,直接将用户输入输出到浏览器,则浏览器将会执行用户注入的脚本。
例如:有一个input输入框,要求用户输入名字,用户输入lily<script>alert("hello
world")</script>,服务器接收到用户的输入,并且直接将用户输入输出到页面上,则会有hello world
的alert对话框出现。如果说这是XSS黑客的自娱自乐,那么盗取用户信息的XSS就不那么友好了。如果用户通过注入脚本,盗取你的用户信息如cookie的内容,仿冒正常用户,进行相应的操作,则危害会更大。获取用户的cookie信息非常简单,只需要使用js获取document.cookie,即可以得到。为了便于分析,我们将在用户输入名字框中输入:lily<script>alert(document.cookie)</script>,则你就可以看到你的cookie信息显示在alert对话框中了。
XSS的分类
根据XSS造成的影响,可以将XSS分为非持久型和持久型。
1.非持久型,也叫反射型XSS。通过GET和POST方法,向服务器端输入数据。用户输入的数据通常被放置在URL的query
string中,或者是form
数据中。如果服务器端对输入的数据不进行过滤,验证或编码,就直接将用户输入的信息直接呈现给客户,则可能会造成反射型XSS。反射型XSS是比较普遍的XSS,其危害程度通常被认为较小。但是某些反射型XSS造成的后果会很严重,如在输入框的name中输入<meta
http-equiv="refresh" content="5"
/>,服务器不加处理,将name的值直接送到浏览器,则浏览器会每5秒自动刷新一次。严重者会导致服务器崩溃。
2.持久型,也叫存储型XSS。通常是因为服务器端将用户输入的恶意脚本没有通过验证就直接存储在数据库,并且每次通过调用数据库的方式,将数据呈现在浏览器上。则该XSS跨站脚本攻击将一直存在。若其他用户访问该页面,则恶意脚本就会被触发,用于盗取其他用户的私人信息。
常用XSS方式分为以下几种:
1. 输入框中直接输入恶意脚本,如:
><script>alert(document.cookie)</script>
2. 输入框中输入html标签,在标签中嵌入恶意脚本,如src,href,css style等。
<IMG SRC="javascript:alert('XSS');">;
<BODY BACKGROUND="javascript:alert('XSS')">
<STYLE>li {list-style-image: url("javascript:alert('XSS')");}</STYLE><UL><LI>XSS</br>
3.将恶意脚本注入在event事件中,如onClick,onBlur,onMouseOver等事件。
<a onmouseover="alert(document.cookie)">xxs link</a>
4. 在remote style sheet,javascript中,如
<LINK REL="stylesheet" HREF="javascript:alert('XSS');">
<SCRIPT/SRC="http://ha.ckers.org/xss.js"></SCRIPT>
5. META 标签,如
<meta http-equiv="refresh" content="5" />
<META HTTP-EQUIV="Set-Cookie" Content="USERID=<SCRIPT>alert('XSS')</SCRIPT>">
如何预防以上两种XSS攻击?
1. 在输入流中截住form data中的恶意脚本
研究两种XSS攻击,如反射型和存储型XSS攻击,其恶意脚本都是来自用户的输入。因此,可以使用过滤用户输入的方法对恶意脚本进行过滤。对简单的HTTP请求,一般使用GET和POST方法。当使用GET时,用户输入的数据将被放入地址栏的URL中,如:http://xxxx?name1=value1&name2=value2…..。其中,URL之后会放入键值对,对应name1的值为value1,name2的值为value2,等等。而对于POST方法,则用户输入数据仍然以name1=value1&name2=value2.。。。,但是数据键值对不会放进URL之后,而是放进了request的body中。因此,我们得到一个结论,所有的数据都存储在request中,我们可以截下进入server的每一个request,对用户的输入数据进行恶意脚本清理。其中有效的一个方法就是使用spring的filter。代码示例如下,在web.xml中加入以下代码段:
<filter>
<filter-name>XSS</filter-name>
<filter-class>com.springapp.domain.XssFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XSS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
其中XssFilter为自定义的class,该类必须实现Filter类,在XssFilter类中实现doFilter函数。
public class XssFilter implements Filter {
private FilterConfig filterConfig;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
@Override
public
void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(new RequestWrapper((HttpServletRequest) request), new ResponseWrapper((HttpServletResponse) response));
}
@Override
public void destroy() {
this.filterConfig = null;
}
}
那么我们怎样对每个request都进行过滤操作呢?怎么样对用户输入的数据进行操作呢?form数据都存储在什么地方传给servlet的呢?
通常情况下,可以通过调用request.getParameter来获得单个对应name对应的value。若form的传入参数中,一个name值对应多个value,则可以使用request.getParameterValues来获得name值的多个对应值。少数情况下,当你需要raw
request的适合,可以使用getReader和getInputStream。
但是我们可以发现,直接对httpServletRequest的parameter进行set操作会报错,因此需要使用HttpServletRequestWrapper。HttpServletRequestWrapper允许我们重写servletRequest的各种方法,以便对request进行直接操作。
因此,我们可以在自定义的RequestWrapper中,对getParameter和getParameterValues进行重写,从而达到对各个用户输入的form参数的值进行过滤,滤掉form data中的恶意脚本。以下为示例代码:
public String[] getParameterValues(String parameter) {
String[] values = super.getParameterValues(parameter);
if (values==null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = xssClean(values[i]);
}
return encodedValues;
}
public String getParameter(String parameter) {
String value = super.getParameter(parameter);
if (value == null) {
return null;
}
return xssClean(value);
}
2. 在输入流中检测滤掉来自其他网站的URL中的恶意脚本
当用户不小心点击了被其他黑客提供的假冒URL,则可能在该URL中注入恶意脚本。因此,也需要对这种情况进行处理。因此为确保其他在header中的恶意脚本,需要对request.getHeader进行重写。以下为例子:
public String getHeader(String name) {
String value = super.getHeader(name);
if (value == null)
return null;
return xssClean(value);
}
3. xssClean函数怎样实现才可以过滤掉恶意脚本呢?
如果是java语言,推荐使用antisamy。使用antisamy进行XSS清理非常简单,只需要简单的几个步骤即可达到目的。
1‘. 在pom.xml文件中加入antisamy的dependency,
<dependency>
<groupId>org.owasp.antisamy</groupId>
<artifactId>antisamy</artifactId>
<version>1.5.3</version>
</dependency>
2’.
加入了dependency之后,就可以在xssClean中加入antisamy对恶意脚本进行清理。其中policy.xml是白名单,policy.xml中规定了各个html元素所必须满足的条件。antisamy的精髓之处在于,使用policy文件来规定你的过滤条件,若输入字符串不满足policy文件中的条件,则会过滤掉字符中的恶意脚本,返回过滤后的结果。具体代码如下:
private String xssClean(String value) {
AntiSamy antiSamy = new AntiSamy();
try {
final CleanResults cr = antiSamy.scan(value, Policy.getInstance("policy.xml"), AntiSamy.SAX);
return cr.getCleanHTML();
} catch (ScanException e) {
e.printStackTrace();
} catch (PolicyException e) {
e.printStackTrace();
}
return value;
}
这样,我们就将client端用户输入的request,在server端进行了拦截,并且进行了过滤。对于输出端,XSS的防御将在下一篇文章中进行详细介绍。
转载请注明出处,谢谢。
怎样过滤跨站恶意脚本攻击(XSS)的更多相关文章
- CSRF跨站请求伪造与XSS跨域脚本攻击讨论
今天和朋友讨论网站安全问题,聊到了csrf和xss,刚开始对两者不是神明白,经过查阅与讨论,整理了如下资料,与大家分享. CSRF(Cross-site request forgery):跨站请求伪造 ...
- XSS跨站脚本攻击与CSRF跨站请求伪造攻击的学习总结(转载)
转载自 https://blog.csdn.net/baidu_24024601/article/details/51957270 之前就了解过这方面的知识,但是没有系统地总结.今天在这总结一下,也让 ...
- SpringSecurity原理解析以及CSRF跨站请求伪造攻击
SpringSecurity SpringSecurity是一个基于Spring开发的非常强大的权限验证框架,其核心功能包括: 认证 (用户登录) 授权 (此用户能够做哪些事情) 攻击防护 (防止伪造 ...
- 教你轻松解决CSRF跨站请求伪造攻击
摘要:CSRF(Cross-site request forgery)跨站请求伪造,通过伪装来自受信任用户的请求来利用受信任的网站.与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也 ...
- 安全性测试入门 (三):CSRF 跨站请求伪造攻击和防御
本篇继续对于安全性测试话题,结合DVWA进行研习. CSRF(Cross-site request forgery):跨站请求伪造 1. 跨站请求伪造攻击 CSRF则通过伪装成受信任用户的请求来利用受 ...
- (28)django的中间件(自定义中间件和防范跨站请求伪造攻击)-重要的概念
Django中间件和中间件不是同一种东西 什么是中间件:中间件是一个很大的概念,只要程序和程序之间还有一层程序,用来处理两个程序的整个交互过程的请求.数据等等就叫中间件 Django中间件:是介于re ...
- (22)Ajax的基本使用(实现登录功能和局部刷新以及防止跨站请求伪造攻击)
Ajax的作用 前后端分离的项目,需要交互,就要通过Ajax来完成交互 AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即 ...
- ASP.NET Core中的OWASP Top 10 十大风险-跨站点脚本攻击 (XSS)
不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: https://dotnetcoretutorials.com/201 ...
- 跨站点脚本攻击XSS
来源:http://www.freebuf.com/articles/web/15188.html 跨站点脚本攻击是一种Web应用程序的攻击,攻击者尝试注入恶意脚本代码到受信任的网站上执行恶意操作.在 ...
随机推荐
- k8s restful API 结构分析
k8s的api-server组件负责提供restful api访问端点, 并且将数据持久化到etcd server中. 那么k8s是如何组织它的restful api的? 一, namespaced ...
- CentOS 7.2安装lepus数据库监控系统
环境说明 系统版本 CentOS 7.2 x86_64 软件版本 lepus 3.7 Lepus是一套开源的数据库监控平台,目前已经支持MySQL.Oracle.SQLServer.MongoDB ...
- ANGULARJS: UNDERSTANDING DIRECTIVE SCOPE
https://www.3pillarglobal.com/insights/angularjs-understanding-directive-scope --------------------- ...
- 转: WebView载入一个网页 但是退出对应的activity时, 声音、视频无法停止播放 解决方案(未验证)
1. webview.onPause 2. webview独立进程,杀进程3.小场景可以不用这么复杂有个技巧就是在activity退出的时候加载一个空白页面,就能解决
- 【HTML 元素】标记文字
1.用基本的文字元素标记内容 先看显示效果: 对应HTML代码: <!DOCTYPE html> <html lang="en"> <head> ...
- Android学习(十六) 通过GestureOverlayView进行手势识别
一.使用GestureOverlayView进行手势识别: 1.使用Gestures Builder生成手势文件,Gestures Builder为SDK中的示例项目,使用new-->Other ...
- Python命令行选项參数解析策略
概述 在Python的项目开发过程中,我们有时须要为程序提供一些能够通过命令行进行调用的接口.只是,并非直接使用 command + 当前文件 就ok的,我们须要对其设置可选的各种各样的操作类型.所以 ...
- flask的分页功能
分页是个很通用的东西,在flask中,有一个macro的语法,类似于宏,我们可以将通用的东西通过macro写入单独的html文件以方便维护,减少代码量.下面是我的分页的macro文件render_pa ...
- 【DB2】db2命令Export与Import
环境准备 1.新建表 qinys@Linux:~> db2 "create table tb1(id int,dt timestamp,name varchar(100))" ...
- SpringBoot 框架整合
代码地址如下:http://www.demodashi.com/demo/12522.html 一.主要思路 使用spring-boot-starter-jdbc集成Mybatis框架 通过sprin ...