XSS研究2-来自内部的XSS攻击的防范
引入:
前面我们分2篇文章分别探讨了来自外部的XSS攻击和来自内部的XSS攻击,现在我们来专门探讨如何防范来自内部的XSS攻击。
实践:
http://www.cnblogs.com/crazylqy/p/4146740.html 文章中可以看出,主要的攻击手段无外乎是发送了一段恶意脚本到受害者机器上去运行,所以我们的思路就是,如何让这段脚本失效。
因为脚本的组成部分是<script>和</script>,而这其中最主要的是大于号和小于号字符,所以我们只要在请求中,把
大于号字符,小于号字符处理下,让其没办法通过
Http发送到受害者机器上,当然就没办法在受害者机器上组成一段恶意脚本了。但是如果我们的内容中真的有大于号和小于号,并且作为内容的一部分而最终目
的并不是入侵怎么办?我们只要吧大于号,小于号进行全角化处理就可以了,因为只有half-width的大于号和小于号能组
成<script>,</script>,而full-width的大于号和小于号是不可以被对待
成<script>,</script>的。
读者可能又问,现在就算你不让我输入大于号和小于号,但是我可以以unicode字符的形式输入这些字符啊,比如大于号叫 >
小于号叫< 所以我只要在恶意脚本中所有用到大于小于的地方全部用这些替换,一样可以达到入侵的目的。
所以,我们必须对于这种&,#还有其他特殊字符也进行处理。
综上所述,我们大概明白怎么做了,我们只要做一个过滤器,然后把这些特殊字符都过滤掉就可以了。
web.xml中定义一个过滤器:
<?xml version="1.0" encoding="UTF-8"?> xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name>XSSDemo</display-name> <filter> <filter-name>XSS Filter</filter-name> <filter-class>com.charles.study.XSSFilter</filter-class> </filter> <filter-mapping> <filter-name>XSS Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app> |
然后我们定义一个 XSSHttpServletRequestWrapper,它是HttpServletRequest的封装器,其中会吧一些特殊字符全部处理掉,被处 理的特殊字符就是那些会造成script的字符,吧他们全部“全角化”,来避免植入恶意代码,这是通过覆写getParameter()和 getHeader()方法来实现的:
package com.charles.study;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;/** * This is the HTTPServletRequestWrapper class ,which overrides the default implementation * of getParameter() and getHeader() method ,it will handle the characters that may cause XSS * @author charles.wang * */public class XSSHttpServletRequestWrapper extends HttpServletRequestWrapper { public XSSHttpServletRequestWrapper(HttpServletRequest request) { super(request); } /** * Override the original getParameter() method , * so that it can filter all the parameter name and parameter value * then use replace the special character that may cause XSS attack */ @Override public String getParameter(String name) { String value = super.getParameter(encodeXSS(name)); //the following sentences will be replaced by logging sentence in actual project System.out.println("The original value received from getParameter() is:"+value); if (value != null) { value = encodeXSS(value); } //the following sentences will be replaced by logging sentence in actual project System.out.println("After handling XSS ,the actual value is:"+value); System.out.println(); return value; } /** * Override the original getHeader() method , * so that it can filter all the parameter name and parameter value * then use replace the special character that may cause XSS attack */ @Override public String getHeader(String name) { String value = super.getHeader(encodeXSS(name)); //the following sentences will be replaced by logging sentence in actual project System.out.println("The original value received from getHeader() is:"+value); if (value != null) { value = encodeXSS(value); } //the following sentences will be replaced by logging sentence in actual project System.out.println("After handling XSS ,the actual value is:"+value); System.out.println(); return value; } /** * replace all the characters that may cause XSS attack from half-width character * to full-width character * * @param s * @return */ private String encodeXSS(String s) { if (s == null || "".equals(s)) { return s; } StringBuilder sb = new StringBuilder(s.length() + 16); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); switch (c) { //handle the '<' and '>' which can be used for constructing <script> and </script> case '>': sb.append('>'); break; case '<': sb.append('<'); break; //since the html can support the characters using $#number format //so here also need to escape '#','&' and quote symbol case '\'': sb.append('‘'); break; case '\"': sb.append('“'); break; case '&': sb.append('&'); break; case '\\': sb.append('\'); break; case '#': sb.append('#'); break; //if not the special characters ,then output it directly default: sb.append(c); break; } } return sb.toString(); }} |
最后,我们来定义过滤器的实现,我们在doFilter()方法体中会吧所有的Http请求包装为我们自定义的包装器,这样所有当请求相关内容时候,我们包装器中就会对有可能引起XSS攻击的特殊字符处理,从而预防XSS 攻击。
package com.charles.study;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;/** * XSSFilter that can be used to filter invalid character which may cause XSS attack * @author charles.wang * */public class XSSFilter implements Filter { @Override public void destroy() { } /** * now the doFilter will filter the request ,using the Wrapper class to wrap the request * and in the wrapper class, it will handle the XSS issue */ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { XSSHttpServletRequestWrapper xssRequest = new XSSHttpServletRequestWrapper( (HttpServletRequest) request); chain.doFilter(xssRequest, response); } @Override public void init(FilterConfig arg0) throws ServletException { }} |
我们基于上面的实现来做例子,我们回忆以前文章,假如在恶意页面的输入框中输 入<script>alert("Attack");</script>时候,在受害者页面会弹出一个alert对话框,也就是 说这个恶意js在受害者的自己域上执行了从而达到内部XSS攻击的目的。
那么现在呢?假如我们在页面中输入同样的脚本:

因为我们启用了XSS的过滤器,所以他们会自动吧这些大于小于转为全角,从而破坏其形成一段脚本,我们来看下服务器日志:

因为做了半角到全角的转换,所以最终页面不会弹出那个alert了,而且正确的显示了:

总结:
其实这种解决方案很common,其思路就是类似于海关检查,大家都知道爆炸物和有威胁的物品(恶意脚本)大多数都是硫磺,金属('<','>')等等,那么我只要在过海关的时候(用户提交输入内容框)对这些危险物品进行清查,该扣留的扣留,该销毁的销毁(我们的encodeXSS方法,吧这些< ,>全部全角化)) ,这样就算这个人通过了检查,他因为没有了硫磺和金属物品,所以他没办法制作有威胁的炸弹了(到我们例子就是我们把特殊字符全部全角化了之后,它就不再能形成一个脚本了),于是达到防止内部XSS攻击的结果。
还可以换成HTML转义字符
| package cn.richinfo.answerclub.filter;
import java.util.regex.Matcher; import javax.servlet.http.HttpServletRequest; /** public XssHttpServletRequestWrapper(HttpServletRequest request) { /** /** String value = super.getHeader(xssEncode(name)); /** s = s.replaceAll("&", "&"); s = regexReplace("<([^>]*?)(?=<|$)", "<$1", s); //s = s.replaceAll("\\|", ""); private static String regexReplace(String regex_pattern, /** /** return req; |
XSS研究2-来自内部的XSS攻击的防范的更多相关文章
- XSS研究1-来自外部的XSS攻击
引入: 上文中我们的例子是研究了来自内部的XSS攻击,通过输送一段有害js代码到受害者的机器,让其在受害者的域上运行这段有害JS代码来得到入侵目的.现在我们来看下来自外部的XSS攻击. 实践: 下面还 ...
- 来自内部的XSS攻击的防范
来自内部的XSS攻击的防范 引入:前面我们分2篇文章分别探讨了来自外部的XSS攻击和来自内部的XSS攻击,现在我们来专门探讨如何防范来自内部的XSS攻击. 实践:其实从 http://www.2cto ...
- XSS与CSRF两种跨站攻击比较
XSS:跨站脚本(Cross-site scripting) CSRF:跨站请求伪造(Cross-site request forgery) 在那个年代,大家一般用拼接字符串的方式来构造动态SQL 语 ...
- 总结 XSS 与 CSRF 两种跨站攻击
前言 在那个年代,大家一般用拼接字符串的方式来构造动态 SQL 语句创建应用,于是 SQL 注入成了很流行的攻击方式.在这个年代, 参数化查询 [1] 已经成了普遍用法,我们已经离 SQL 注入很远了 ...
- 总结XSS与CSRF两种跨站攻击
XSS:跨站脚本(Cross-site scripting),实际应是"CSS",但由于和层叠样式表CSS名称冲突,故改为"XSS" CSRF:跨站请求伪造(C ...
- XSS 与 CSRF 两种跨站攻击
在前几年,大家一般用拼接字符串的方式来构造动态 SQL 语句创建应用,于是 SQL 注入成了很流行的攻击方式, 但是现在参数化查询 已经成了普遍用法,我们已经离 SQL 注入很远了.但是历史同样悠久的 ...
- XSS与CSRF两种跨站攻击总结
在那个年代,大家一般用拼接字符串的方式来构造动态 SQL 语句创建应用,于是 SQL 注入成了很流行的攻击方式.在这个年代, 参数化查询 [1] 已经成了普遍用法,我们已经离 SQL 注入很远了.但是 ...
- XSS攻击及防范
1.什么是XSS攻击 跨站脚本攻击(Cross Site Scripting),攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到 ...
- 二十五:XSS跨站值原理分类及攻击手法
HTML DOM树 XSS跨站产生原理,危害,特点 本质,产生层面,函数类,漏洞操作对应层,危害影响,浏览器内核版本 XSS是什么? XSS全称跨站脚本(Cross Site Scripting),为 ...
随机推荐
- 采用Spring AOP+Log4j记录项目日志
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6567672.html 项目日志记录是项目开发.运营必不可少的内容,有了它可以对系统有整体的把控,出现任何问题 ...
- 新人小达之wpf
Wpf学习之路-- 第一次写微博,可能内容不够精细,但目的就是把问题讲明白,让看到文章的小伙伴们少走弯路. 由于公司的需要,需要学习.net的一门新技术-wpf. 要说wpf是什么框架?模式?架构? ...
- Python可视化学习(2):Matplotlib快速绘图基础
Matplotlib将大部分的绘图对象都封装成为对象,故理论上所有的图表元素(如Line2D, Text,Label等)都是对象,都可以将其在图表中提取出来并配置实例的属性.同时,Matplotlib ...
- JS弹出框
一.JS三种最常见的对话框 1.alert()警告框 alert是警告框,只有一个按钮"确定"无返回值,警告框经常用于确保用户可以得到某些信息.当警告框出现后,用户需要点 ...
- Service详解
/** * 后台执行的定时任务 */ public class LongRunningService extends Service { @Override public IBinder onBind ...
- PHP对象相关知识点的总结
对象传递:一种说法是"PHP对象是通过引用传递的",更准确的说法是别名(标识符)传递,即它们都保存着同一个标识符(ID)的拷贝,这个标识符指向同一个对象的真正内容. <?ph ...
- Mac系统-java环境搭建_01
一.安装jdk 下载地址:http://www.oracle.com/technetwork/Java/javase/downloads/index-jsp-138363.html 1.傻瓜式安装下一 ...
- jmeter参数化随机取值实现
jmeter能用来做参数化的组件有几个,但是都没有随机取值的功能,遇到随机取值的需求怎么办呢? 突发奇想,可以用函数__CSVRead()来实现: __CSVRead() CSV file to ge ...
- JSON对象、JSON字符串的相互转换
JSON对象.JSON字符串的相互转换 json的格式: 第一种方式: 单一的json字符串,转换成json对象时,需要 eval('(' + json + ')');这样的格式,中间需要加括号 va ...
- T_SQL编程赋值、分支语句、循环
咱们在C#中会常用到赋值.循环.分支语句什么的 今天咱们来看下当初在C#用到的一点东西放到SQL中是怎么使用的 创建变量 在C#中创建一个值类型变量很简单 int a:这就可以了 SQL: decla ...