拓冰建站拓冰建站
首页 / 资讯中心 / 正文

使用Jsoup防御XSS攻击

一、前言跨站脚本攻击(Cross Site Scripting)为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码当用户浏览该页之时嵌入其中Web里面的Script代码会被执行从而达到恶意攻击用户的目的。使用Jsoup可以有效的过滤不安全的代码。Jsoup使用白名单的机制来预防XSS攻击比如白名单中规定只允许span 标签的存在那么其他标签都会被过滤掉。二、常见的XSS攻击比如页面的某个表单允许用户输入任意内容当某个调皮的用户输入如下内容保存后你会发现页面文字都变成了红色或者输入scriptfor(var i0;i10;i){alert(“fuck you”);}保存后页面将弹窗10次三、引入Jsoup使用Maven构建一个简单的Spring Boot项目在pom中引入!-- https://mvnrepository.com/artifact/org.jsoup/jsoup --dependencygroupIdorg.jsoup/groupIdartifactIdjsoup/artifactIdversion1.13.1/version/dependency四、JsoupUtil创建一个JsoupUtil工具类/** * Xss过滤工具 * wno704 */publicclassJsoupUtil{privatestaticfinalWhitelistwhitelistWhitelist.basicWithImages();/* * 配置过滤化参数,不对代码进行格式化 */privatestaticfinalDocument.OutputSettingsoutputSettingsnewDocument.OutputSettings().prettyPrint(false);static{/* * 富文本编辑时一些样式是使用style来进行实现的 比如红色字体 stylecolor:red; 所以需要给所有标签添加style属性 */whitelist.addAttributes(:all,style);}publicstaticStringclean(Stringcontent){returnJsoup.clean(content,,whitelist,outputSettings);}}这里采用的白名单为basicWithImagesJsoup内置了几种常见的白名单供我们选择如下表所示白名单对象标签说明none无只保留标签内文本内容simpleTextb,em,i,strong,u简单的文本标签basica,b,blockquote,br,cite,code,dd,dl,dt,em,i,li,ol,p,pre,q,small,span,strike,strong,sub,sup,u,ul基本使用的标签basicWithImagesbasic 的基础上添加了 img 标签 及 img 标签的 src,align,alt,height,width,title 属性基本使用的加上 img 标签relaxeda,b,blockquote,br,caption,cite,code,col,colgroup,dd,div,dl,dt,em,h1,h2,h3,h4,h5,h6,i,img,li,ol,p,pre,q,small,span,strike,strong,sub,sup,table,tbody,td,tfoot,th,thead,tr,u,ul在 basicWithImages 的基础上又增加了一部分部分标签五、XssHttpServletRequestWrapper创建一个XssHttpServletRequestWrapper同过重写getParameter()getParameterValues()和getHeader()方法来过滤HTTP请求中参数包含的恶意字符publicclassXssHttpServletRequestWrapperextendsHttpServletRequestWrapper{HttpServletRequestorgRequestnull;privatebooleanisIncludeRichTextfalse;/** * Constructs a request object wrapping the given request. * * param request The request to wrap * throws IllegalArgumentException if the request is null */publicXssHttpServletRequestWrapper(HttpServletRequestrequest){super(request);orgRequestrequest;this.isIncludeRichTextisIncludeRichText;}/** * 覆盖getParameter方法将参数名和参数值都做xss过滤如果需要获得原始的值则通过super.getParameterValues(name)来获取 * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖 */OverridepublicStringgetParameter(Stringname){if((content.equals(name)||name.endsWith(WithHtml))!isIncludeRichText){returnsuper.getParameter(name);}nameJsoupUtil.clean(name);Stringvaluesuper.getParameter(name);if(StringUtils.isNotBlank(value)){valueJsoupUtil.clean(value);}returnvalue;}OverridepublicString[]getParameterValues(Stringname){String[]arrsuper.getParameterValues(name);if(arr!null){for(inti0;iarr.length;i){arr[i]JsoupUtil.clean(arr[i]);}}returnarr;}/** * 覆盖getHeader方法将参数名和参数值都做xss过滤如果需要获得原始的值则通过super.getHeaders(name)来获取 * getHeaderNames 也可能需要覆盖 */OverridepublicStringgetHeader(Stringname){nameJsoupUtil.clean(name);Stringvaluesuper.getHeader(name);if(StringUtils.isNotBlank(value)){valueJsoupUtil.clean(value);}returnvalue;}/** * 获取原始的request */publicHttpServletRequestgetOrgRequest(){returnorgRequest;}/** * 获取原始的request的静态方法 */publicstaticHttpServletRequestgetOrgRequest(HttpServletRequestreq){if(reqinstanceofXssHttpServletRequestWrapper){return((XssHttpServletRequestWrapper)req).getOrgRequest();}returnreq;}}六、XssFilter创建XssFilter同过使用上面定义的XssHttpServletRequestWrapper类中的getParameter()等方法来保证参数得到了过滤Slf4jpublicclassXssFilterimplementsFilter{// 是否过滤富文本内容privatestaticbooleanIS_INCLUDE_RICH_TEXTfalse;publicListStringexcludesnewArrayListString();Overridepublicvoidinit(FilterConfigfilterConfig)throwsServletException{log.info(------------ xss filter init ------------);StringisIncludeRichTextfilterConfig.getInitParameter(isIncludeRichText);if(StringUtils.isNotBlank(isIncludeRichText)){IS_INCLUDE_RICH_TEXTBooleanUtils.toBoolean(isIncludeRichText);}StringtempfilterConfig.getInitParameter(excludes);if(temp!null){String[]urltemp.split(,);for(inti0;url!nulliurl.length;i){excludes.add(url[i]);}}}OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{log.info(------------ xss filter doFilter ------------);HttpServletRequestreq(HttpServletRequest)request;HttpServletResponseresp(HttpServletResponse)response;if(handleExcludeURL(req,resp)){chain.doFilter(request,response);return;}XssHttpServletRequestWrapperxssRequestnewXssHttpServletRequestWrapper((HttpServletRequest)request);chain.doFilter(xssRequest,response);}Overridepublicvoiddestroy(){log.info(------------ xss filter destroy ------------);}privatebooleanhandleExcludeURL(HttpServletRequestrequest,HttpServletResponseresponse){if(excludesnull||excludes.isEmpty()){returnfalse;}Stringurlrequest.getServletPath();for(Stringpattern:excludes){PatternpPattern.compile(^pattern);Matchermp.matcher(url);if(m.find())returntrue;}returnfalse;}}七、Spring Boot中配置XssFilter使用JavaConfig的形式配置ConfigurationpublicclassWebConfig{BeanpublicFilterRegistrationBeanxssFilterRegistrationBean(){FilterRegistrationBeanfilterRegistrationBeannewFilterRegistrationBean();filterRegistrationBean.setFilter(newXssFilter());filterRegistrationBean.setOrder(1);filterRegistrationBean.setEnabled(true);filterRegistrationBean.addUrlPatterns(/*);MapString,StringinitParametersnewHashMapString,String();initParameters.put(excludes,/favicon.ico,/img/*,/js/*,/css/*);initParameters.put(isIncludeRichText,true);filterRegistrationBean.setInitParameters(initParameters);returnfilterRegistrationBean;}}
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门