说到 XSS 攻击,前边已经有两篇文章在讲这个事了,这次又拿出来说,主要是针对近期工作中的一些新的问题。那么之前是怎么解决问题的呢?为什么又要换解决方式?以下就具体的跟大家分享一下。


旧方案


公司的測试团队发现这个问题之后,就要求尽快的解决,在网上查了非常多相关的资料,也翻阅了基本安全方面的书,基于 XSS 的攻击原理,自己写了一个 Filter,并在该 Filter 中增加了对各种请求的处理代码。首先是拦截浏览器发出的请求,然后对拦截到的请求进行过滤,获取參数列表,參数值列表(包含表单提交),然后对这些參数值进行危急字符的过滤处理,处理的过程中分为两种情况。

当中一种是把危急字符进行转换,保留原来的语意,在适当的时候进行还原,当然,这样的情况下危急字符还是存在的,仅仅只是是换了一种相对安全的形式。这样的情况的优点是,保证了请求的原始性,可是对数据库或文件系统产生一些不必要的垃圾信息。为什么这么说呢,由于普通的用户在正常的操作下是不会包括这些非法字符的,仅仅有在非法入侵的情况下才会出现这样的情况,而对于危急字符的转换就是一种间接的保护措施。

对于另外一种情况,不是对危急字符进行转换,而是把请求中的危急字符进行过滤,使得请求纯净化,把非法的字符过滤掉,这样以来,进入数据库或文件系统的就不过合法的语句。这样的情况也会有他的利弊。比方,在过滤的过程中,可能把用户的某些正常请求參数值也给清理掉,这样就不能保证请求的原始性。但系统的安全性方面却大大的提高了。为了避免用户的请求失真,我们能做的就是尽量的避开用户能够输入的特殊字符,在注冊、登录、或者其它的请求中,规定用户能够使用的特殊字符,对那些不提倡使用的字符进行过滤和处理。


问题


在旧的的方案提交给測试团队之后,非常大一部分的 XSS 攻击问题已经不存在了,但又出现了另外一个问题,在登录的过程中,偶尔会把验证码给过滤掉,另一些不定的 URL 会时不时的漏掉,尽管在 web.xml 配置了全局的请求,但还是会出现这种问题。測试团队给出的报告中显示,还有少量的 XSS 攻击存在,让我尽快解决。

针对这个问题,我又研究了问题所在区域的源码,并结合自己写的 XSSFilter,发现了2点问题。

其一,是后台的验证逻辑并不完整,对于提交过来的请求,并没有进行对应的处理。

其二,是 XSSFilter 写的有问题,正如我上面讲到的情况一,仅仅是把危急字符进行转换,并没有从根本上解决这个问题。

俗话说,久病成良医。那么,总想着一件事,问题解决起来也总会是事半功倍的。


新方案


对于出现的问题,我这里有两点须要说,其一就是针对后台的验证逻辑,这个没有必要再具体说了,无非即可完好验证逻辑,针对可能出现的情况进行抽象,抽出通用的验证逻辑,对于个别的验证就单独处理,只是还是要考虑代码的复用性。

其二,是关于 XSS 攻击全局处理的。我这里给出两种解决方式,详述例如以下。

方案一

假设你遇到的情况,对与用户的输入、输出有明白的限制,并且对于特殊字符也有明白的规定,那么你能够自己写一个 XSSFilter,使用上面提到的情况二,对不建议输入的特殊字符进行过滤和清理,包含 SQL 注入的一些敏感信息,都是要过滤掉的。主要的 Filter 网上都有,你要做的就是针对自己的业务,再增加对危急字符的处理就可以。

方案二

想到一句老话,站在巨人的肩膀上。另外一种方案,就是站在巨人的肩膀上。推荐一款开源插件,xssProject,详细作者不详。GoogleCode 中提供对应了的源码。想研究的能够自己去找一下。以下着重讲一下,怎样在项目中集成 xssProject,并使之为我们服务。

首先,项目中须要引入 xssProtect-0.1.jar、antlr-3.0.1.jar、antlr-runtime-3.0.1.jar 等3个 jar 包。

然后,封装 request,代码例如以下。

<span style="font-family:Comic Sans MS;">public class NewXssHttpServletRequestWrapper extends HttpServletRequestWrapper {

	HttpServletRequest orgRequest = null;

	public NewXssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
orgRequest = request;
} /**
* 覆盖getParameter方法,将參数名和參数值都做xss过滤。<br/>
* 假设须要获得原始的值,则通过super.getParameterValues(name)来获取<br/>
* getParameterNames,getParameterValues和getParameterMap也可能须要覆盖
*/
@Override
public String getParameter(String name)
{
System.out.println("NewXssFilter处理前的 Value = " + super.getParameterValues(name)); String value = super.getParameter(xssEncode(name));
if (value != null)
{
value = xssEncode(value);
} System.out.println("NewXssFilter处理后的 Value = " + value); return value;
} /**
* 覆盖getHeader方法,将參数名和參数值都做xss过滤。<br/>
* 假设须要获得原始的值,则通过super.getHeaders(name)来获取<br/> getHeaderNames 也可能须要覆盖
*/
@Override
public String getHeader(String name)
{ String value = super.getHeader(xssEncode(name));
if (value != null)
{
value = xssEncode(value);
}
return value;
} /**
* 将easy引起xss漏洞的半角字符直接替换成全角字符
*
* @param s
* @return
*/
private static String xssEncode(String s)
{
if (s == null || s.isEmpty())
{
return s;
} StringReader reader = new StringReader( s );
StringWriter writer = new StringWriter();
try {
HTMLParser.process( reader, writer, new XSSFilter(), true ); return writer.toString();
}
catch (NullPointerException e) {
return s;
}
catch(Exception ex)
{
ex.printStackTrace();
} return null; } /**
* 获取最原始的request
*
* @return
*/
public HttpServletRequest getOrgRequest()
{
return orgRequest;
} /**
* 获取最原始的request的静态方法
*
* @return
*/
public static HttpServletRequest getOrgRequest(HttpServletRequest req)
{
if (req instanceof NewXssHttpServletRequestWrapper)
{
return ((NewXssHttpServletRequestWrapper) req).getOrgRequest();
} return req;
} }</span>

再然后,创建过滤器 NewXssFilter 。

<span style="font-family:Comic Sans MS;">public class NewXssFilter implements Filter {

	FilterConfig filterConfig = null;

	@Override
public void destroy() {
this.filterConfig = null;
} @Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
String path = ((HttpServletRequest) request).getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName()
+ ":" + request.getServerPort() + path + "/"; // HTTP 头设置 Referer过滤
String referer = ((HttpServletRequest) request).getHeader("Referer"); // REFRESH
if (referer != null && referer.indexOf(basePath) < 0) {
((HttpServletRequest) request).getRequestDispatcher(
((HttpServletRequest) request).getRequestURI()).forward(
((HttpServletRequest) request), response);
System.out.println("referer不为空,referer >>>>>>>>>>>>>> " + referer);
}
NewXssHttpServletRequestWrapper xssRequest = new NewXssHttpServletRequestWrapper((HttpServletRequest) request);
chain.doFilter(xssRequest, response);
} @Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
} }</span>

最后,在 web.xml 中配置过滤器 。


<span style="font-family:Comic Sans MS;"><filter>
<filter-name>XssSqlFilter</filter-name>
<filter-class>com.***.web.common.NewXssFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XssSqlFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping></span>

结束语


以上这些就是所有的内容了,针对 XSS 攻击的解决方式,写出来跟大家分享,个人建议使用 xssProject 来解决这一问题。毕竟 xssProject 已经提供了非常完好的过滤、处理方案,你能够通过研究他的代码来进行扩展,假设须要的话。最后附上 xssProject 所需的三个 jar 包。




WEB安全实战(五)XSS 攻击的第二种解决方式(推荐)的更多相关文章

  1. 使用 PHP 构建的 Web 应用如何避免 XSS 攻击

    本文首先简单介绍开发测试人员如何对 Web 应用进行 XSS 漏洞测试,如何借助工具绕过客户端 JavaScript 校验输入恶意数据:然后针对使用 PHP 语言构建的 Web 站点,从在输出端对动态 ...

  2. Java Web使用过滤器防止Xss攻击,解决Xss漏洞

    转: Java Web使用过滤器防止Xss攻击,解决Xss漏洞 2018年11月11日 10:41:27 我欲乘风,直上九天 阅读数:2687   版权声明:本文为博主原创文章,转载请注明出处!有时候 ...

  3. 使用Typescript重构axios(十九)——请求取消功能:实现第二种使用方式

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  4. python_并发编程——多进程的第二种启动方式

    1.多进程的第二种启动方式 import os from multiprocessing import Process # 创建一个自定义类,继承Process类 class MyProcess(Pr ...

  5. Web 安全漏洞之 XSS 攻击

    什么是 XSS 攻击 XSS(Cross-Site Scripting)又称跨站脚本,XSS的重点不在于跨站点,而是在于脚本的执行.XSS是一种经常出现在 Web 应用程序中的计算机安全漏洞,是由于 ...

  6. Web Api全局预防Xss攻击

    本文转载自https://www.cnblogs.com/ruanyifeng/p/4739807.html.对第二种过滤方法的代码进行了一些修改和注释,记录一下免得以后忘了.已经测试过,应该可以直接 ...

  7. Web APi之认证(Authentication)两种实现方式后续【三】(十五)

    前言 之前一直在找工作中,过程也是令人着实的心塞,最后还是稳定了下来,博客也停止更新快一个月了,学如逆水行舟,不进则退,之前学的东西没怎么用,也忘记了一点,不过至少由于是切身研究,本质以及原理上的脉络 ...

  8. Web APi之认证(Authentication)两种实现方式【二】(十三)

    前言 上一节我们详细讲解了认证及其基本信息,这一节我们通过两种不同方式来实现认证,并且分析如何合理的利用这两种方式,文中涉及到的基础知识,请参看上一篇文中,就不再叙述废话. 序言 对于所谓的认证说到底 ...

  9. 转 Web APi之认证(Authentication)两种实现方式【二】(十三)

    前言 上一节我们详细讲解了认证及其基本信息,这一节我们通过两种不同方式来实现认证,并且分析如何合理的利用这两种方式,文中涉及到的基础知识,请参看上一篇文中,就不再废叙述废话. 序言 对于所谓的认证说到 ...

随机推荐

  1. 使用Canvas和Paint自己绘制折线图

    主要用于Canvas一个特别简单的小demo. 能够手动点击看每一个月份的数据.很easy.就是用paint在canvas上画出来的. 主要内容就是计算左边价格的位置,以下日期的位置,三根虚线的位置, ...

  2. BZOJ 3589 动态树 树链拆分+纳入和排除定理

    标题效果:鉴于一棵树.每个节点有一个右值,所有节点正确启动值他们是0.有两种操作模式,0 x y代表x右所有点的子树的根值添加y. 1 k a1 b1 a2 b2 --ak bk代表质疑. 共同拥有者 ...

  3. Scrum三头猪

    猪和鸡在过去进入业务合作.他们都打算开一家餐厅,它的售价火腿和鸡蛋. 这想了一下时间猪,我用他的肉,鸡只是用它生下的蛋.万一生意失败,我自己的命就没,,没有不论什么影响. 1. Scrum两类关系人 ...

  4. struts1吊牌&lt;logic:iterate&gt;

    <logic:iterate>主要用于处理网页上的输出集合,集合是其中一般下列之一: 1. java对象的数组 2. ArrayList.Vector.HashMap等 具体使用方法请參考 ...

  5. 怎么理解Condition(转)

    在java.util.concurrent包中,有两个很特殊的工具类,Condition和ReentrantLock,使用过的人都知道,ReentrantLock(重入锁)是jdk的concurren ...

  6. JavaScript阻止事件冒泡(兼容IE、Chrome、FF)

    这里仅仅是一个简单代码demo,因为时间问题并未做深入研究,因为今天做项目时要用到阻止事件冒泡的内容,找了好多才找到一个可以使用的,特记录之. <!DOCTYPE HTML> <ht ...

  7. asp.net下cookie 的基础使用

    cookie作为在B/S开发中经常被使用到的东西,asp.net必然提供了现成的东西给我们使用. 就是这个对象:HttpCookie,当然了,对于asp.net来说,Request和Response中 ...

  8. java线程API学习 线程池ThreadPoolExecutor(转)

    线程池ThreadPoolExecutor继承自ExecutorService.是jdk1.5加入的新特性,将提交执行的任务在内部线程池中的可用线程中执行. 构造函数 ThreadPoolExecut ...

  9. Codeforces 135A-Replacement(思维)

    A. Replacement time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  10. 大数据系列修炼-Scala课程11

    接着昨天的list,也是学习集合的相关知识 ListBuffer.ArrayBuffer.Queue.stack相关操作 1.ListBuffer.ArrayBuffer代码实现:ListBuffer ...