XSS安全漏洞修复解决方案
背景:等保测评公司针对我系统进行了一次渗透测试,并发现存在XSS漏洞,现记录修复过程。
框架:SSM。
全站XSS:
漏洞风险等级:中危
涉及页面:全站存在内容输入处
漏洞描述:所有模块可以修改内容处存在XSS,填入恶意代码后触发。
修复建议:过滤所有输入内容。(防止恶意弹窗/跨站脚本/过滤敏感字符/违法信息等)
解决方案
列举方案1:写个DispatcherServlet
import javax.servlet.http.HttpServletRequest;import org.springframework.stereotype.Controller;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerExecutionChain;@SuppressWarnings("serial")
public class DispatcherServletWrapper extends DispatcherServlet {@Overrideprotected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {HandlerExecutionChain chain = super.getHandler(request);Object handler = chain.getHandler();if (!(handler instanceof HandlerMethod)) {return chain;}HandlerMethod hm = (HandlerMethod)handler;if (!hm.getBeanType().isAnnotationPresent(Controller.class)) {return chain;}//仅处理@Controller注解的Beanreturn new HandlerExecutionChainWrapper(chain,request,getWebApplicationContext());}}
在getHandler中返回HandlerExecutionChainWrapper
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;import javax.servlet.http.HttpServletRequest;import org.springframework.beans.factory.BeanFactory;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.FieldCallback;
import org.springframework.util.ReflectionUtils.FieldFilter;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.util.HtmlUtils;public class HandlerExecutionChainWrapper extends HandlerExecutionChain {private BeanFactory beanFactory;private HttpServletRequest request;private HandlerMethod handlerWrapper;private byte[] lock = new byte[0];public HandlerExecutionChainWrapper(HandlerExecutionChain chain,HttpServletRequest request,BeanFactory beanFactory) {super(chain.getHandler(),chain.getInterceptors());this.request = request;this.beanFactory = beanFactory;}@Overridepublic Object getHandler() {if (handlerWrapper != null) {return handlerWrapper;}synchronized (lock) {if (handlerWrapper != null) {return handlerWrapper;}HandlerMethod superMethodHandler = (HandlerMethod)super.getHandler();Object proxyBean = createProxyBean(superMethodHandler);handlerWrapper = new HandlerMethod(proxyBean,superMethodHandler.getMethod());return handlerWrapper;}}/*** 为Controller Bean创建一个代理实例,以便用于 实现调用真实Controller Bean前的切面拦截* 用以过滤方法参数中可能的XSS注入* @param handler* @return*/private Object createProxyBean(HandlerMethod handler) {try {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(handler.getBeanType());Object bean = handler.getBean();if (bean instanceof String) {bean = beanFactory.getBean((String)bean);}ControllerXssInterceptor xss = new ControllerXssInterceptor(bean);xss.setRequest(this.request);enhancer.setCallback(xss);return enhancer.create();}catch(Exception e) {throw new IllegalStateException("为Controller创建代理失败:"+e.getMessage(), e);}}public static class ControllerXssInterceptor implements MethodInterceptor {private Object target;private HttpServletRequest request;private List<String> objectMatchPackages;public ControllerXssInterceptor(Object target) {this.target = target;this.objectMatchPackages = new ArrayList<String>();this.objectMatchPackages.add("com.jwell");}public void setRequest(HttpServletRequest request) {this.request = request;}@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {//对Controller的方法参数进行调用前处理//过滤String类型参数中可能存在的XSS注入if (args != null) {for (int i=0;i<args.length;i++) {if (args[i]==null)continue;if (args[i] instanceof String) {args[i] = stringXssReplace((String)args[i]);continue;}for(String pk:objectMatchPackages) {if (args[i].getClass().getName().startsWith(pk)) {objectXssReplace(args[i]);break;}}}}return method.invoke(target, args);}private String stringXssReplace(String argument) {return HtmlUtils.htmlEscape(argument);}private void objectXssReplace(final Object argument) {if (argument == null)return;ReflectionUtils.doWithFields(argument.getClass(), new FieldCallback(){@Overridepublic void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {ReflectionUtils.makeAccessible(field);String fv = (String)field.get(argument);if (fv != null) {String nv = HtmlUtils.htmlEscape(fv);field.set(argument, nv); }}}, new FieldFilter(){@Overridepublic boolean matches(Field field) {boolean typeMatch = String.class.equals(field.getType());if (request!=null && "GET".equals(request.getMethod())) {boolean requMatch = request.getParameterMap().containsKey(field.getName());return typeMatch && requMatch; }return typeMatch;}});}}
web.xml 替换DispatcherServlet
<!--将org.springframework.web.servlet.DispatcherServlet替换成自己的DispatcherServletWrapper -->
<servlet><servlet-name>SpringMVC</servlet-name><!--安全测试 --><!-- <servlet-class>com.xx.xx.bmms.web.filter.DispatcherServletWrapper</servlet-class> --><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc-bpbj.xml</param-value></init-param><load-on-startup>1</load-on-startup><async-supported>true</async-supported></servlet>
再次测试,已解决,不过此方案本人不推荐,原因(会影响业务,谁用谁知道 哈哈~)
列举方案2:写个filter(推荐)
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;public class XssFilter implements Filter{FilterConfig filterConfig = null;@Overridepublic void destroy() {// TODO Auto-generated method stubthis.filterConfig = null;}@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {// TODO Auto-generated method stubchain.doFilter(new XssShellInterceptor( (HttpServletRequest) request), response);}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// TODO Auto-generated method stubthis.filterConfig = filterConfig;}
XssShellInterceptor类(HttpServletRequestWrapper)
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;public class XssShellInterceptor extends HttpServletRequestWrapper{public XssShellInterceptor(HttpServletRequest request) {super(request);}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] = cleanXSS(values[i]);}return encodedValues;}public String getParameter(String parameter) {String value = super.getParameter(parameter);if (value == null) {return null;}return cleanXSS(value);}public String getHeader(String name) {String value = super.getHeader(name);if (value == null)return null;return cleanXSS(value);}//过滤规则 目前我只配了过滤 script private String cleanXSS(String value) {//value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");//value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");//value = value.replaceAll("'", "& #39;");//value = value.replaceAll("eval\\((.*)\\)", "");value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");value = value.replaceAll("script", "");return value;}}
web.xml 添加filter
<filter><filter-name>XssFilter</filter-name><filter-class>com.xx.xx.bmms.web.filter.XssFilter</filter-class></filter><filter-mapping><filter-name>XssFilter</filter-name><url-pattern>/*</url-pattern> </filter-mapping>
再次测试,已解决。注意:如果web.xml中有多个filter 注意执行顺序。
XSS安全漏洞修复解决方案相关推荐
- dz论坛去掉orum.php,DiscuzX3.4最新论坛漏洞修复解决方案
原标题:DiscuzX3.4最新论坛漏洞修复解决方案 Discuz!论坛目前最新版本为3.4版本,已经好久没有更新了,我们SINE安全在对其网站安全检测的同时发现一处漏洞,该漏洞可导致论坛的后台文件可 ...
- thinkcmf 渗透测试漏洞修复解决方案
近段时间发现很多APP程序用的是thinkcmf,此程序源码存在getshell漏洞,我们Sine安全紧急对此高危漏洞进行了分析和漏洞修复,攻击者可以通过构造特定的请求包get请求即可在远程服务器上执 ...
- 中科方德服务器操作系统找到外置光盘,方德高可信服务器操作系统Meltdown和Spectre漏洞修复-中科方德.PDF...
方德高可信服务器操作系统Meltdown和Spectre漏洞修复-中科方德 方德高可信服务器操作系统Meltdown和 Spectre 漏洞修复指南 导读:近日爆出的Intel CPU特性漏洞分为&q ...
- AppScan漏洞“已解密的登陆请求”修复解决方案
AppScan漏洞"已解密的登陆请求"修复解决方案 参考文章: (1)AppScan漏洞"已解密的登陆请求"修复解决方案 (2)https://www.cnbl ...
- 网站漏洞修复网站安全检测整体解决方案
在很多网站系统构建的一开始,最注重的就是网站程序代码的安全,我们SINE安全对甲方网站公司部署过很多的网站安全系统,之前有一些网站设计公司对于每个项目都会由专人去负责开发与设计,并与甲方网站公司进行沟 ...
- xss漏洞修复踩坑总结
一.前言 最近测试发现系统某个接口有个xss漏洞,比如,保存数据入库时,会把<a>标签保存入库:然后查看列表时,会把<a>标签显示出来: 说是这个漏洞可以构建恶意链接,点击会跳 ...
- Web安全原理剖析(十八)——XSS平台及漏洞修复建议
目录 5.2 使用XSS平台测试XSS漏洞 5.3 XSS漏洞修复建议 5.2 使用XSS平台测试XSS漏洞 XSS平台可自行本地搭建或使用在线平台. 首先在XSS平台注册账号并登录,单击&q ...
- Drupal 网站漏洞修复以及网站安全防护加固方法
2019独角兽企业重金招聘Python工程师标准>>> drupal是目前网站系统使用较多一个开源PHP管理系统,架构使用的是php环境+mysql数据库的环境配置,drupal的代 ...
- [转]Android 常见安全漏洞修复理论与实践
前言 前段时间公司对应用在爱加密上进行了安全扫描,本文将基于爱加密的漏洞分析报告,针对部分内容,介绍理论修复实践 最小化特权准则概念介绍 最小化特权准则,即指组件只能供自身应用调用,尽可能禁止其他应用 ...
最新文章
- 如何把HTML转换成动图,html5实现图片转圈的动画效果——让页面动起来
- python度量学习_Python的差异度量
- asyncdata 获取参数_nuxt的asyncData发送post请求如何传递FormData形式的参数
- 探秘HDR:西瓜、抖音是如何做到让视频的画质堪比影院大片的?
- docker执行容器内的shell_为什么不建议把数据库部署在docker容器内?
- lambda表达式传参
- HP 招聘性能测试PM 北京/上海 长期招聘
- 银行对公业务的发展方向,及多银行资金管理云服务的探索
- iphone设置邮箱设置_如何使用iPhone设置Chromecast
- 如何讲好FISHER确切概率法
- 二十款漂亮CSS字体样式
- 3D Human相关研究:人体、姿态估计、人体重建等
- CSS:N种使用CSS 绘制三角形的方法
- 数据结构与算法--图的广度优先搜索 (BFS)
- SQL Server ansi_null_default | ansi_null_dflt_on
- Hadoop工程师面试题解析
- 大尺度衰落与小尺度衰落
- python输入数字输出月份英文_编写一个程序,输入月份号,输出该月的中文名和英文名。...
- 位图排序算法优化篇-永无止境
- Android版本代号
热门文章
- regionserver.HRegionServerCommandLine: Region server exiting
- poi解决受保护视图问题
- 华为云端服务器使用ModelArts跑MindSpore框架Yolov5
- UIPATH设置定时任务
- 【前沿技术RPA】 万字吃透UiPath如何处理异常
- Android studio 配置 jPBC 2.0.0
- 愿为你破开鱼尾,但不会为你化身浮沫
- 织物缺陷图像识别算法
- 安卓桌面整理app_【小编分享】APP整理大法!跟杂乱无章的手机桌面说拜拜~
- RT-Thread 入门学习笔记 - 熟悉$Sub$$main与$Super$$main