java过滤特殊字符操作(xss攻击解决方案)
XSS ,全名:cross-site scripting(跨站点脚本),是当前 web 应用中最危险和最普遍的漏洞之一。攻击者尝试注入恶意脚本代码(常js脚本)到受信任的网站上执行恶意操作,用户使用浏览器浏览含有恶意脚本页面时,会执行该段恶意脚本,进而影响用户(比如关不完的网站、盗取用户的 cookie 信息从而伪装成用户去操作)等等。
它与 SQL 注入很类似,同样是通过注入恶意指令来进行攻击。但 SQL 注入是在服务器端上执行的,而 XSS 攻击是在客户端上执行的,这点是他们本质区别。
其实,个人感觉对于xss攻击不必区分究竟是反射型XSS、存储型XSS还是DOM Based XSS,只需要知道如何去防护。而防护的最有效的措施就是过滤,对前端页面提交到后台的内容进行过滤。具体如下:
1.解决方法一拦截所有的请求参数,对请求参数中包含特殊字符’<‘或’>’进行过滤。
package com.haier.openplatform.srm.base.filter;import java.io.IOException;import java.util.Iterator;import java.util.Map;import java.util.Set;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import javax.servlet.http.HttpServletResponse;import org.springframework.web.filter.OncePerRequestFilter;public class StringFilter extends OncePerRequestFilter{@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)throws ServletException, IOException {chain.doFilter(new StringFilterRequest((HttpServletRequest)request), response);}}class StringFilterRequest extends HttpServletRequestWrapper {public StringFilterRequest(HttpServletRequest request) {super(request);}@Overridepublic String getParameter(String name) {// 返回值之前 先进行过滤return filterDangerString(super.getParameter(name));}@Overridepublic String[] getParameterValues(String name) {// 返回值之前 先进行过滤String[] values = super.getParameterValues(name);if(values==null){return null;}for (int i = 0; i < values.length; i++) {values[i] = filterDangerString(values[i]);}return values;}@Overridepublic Map getParameterMap() {Map keys = super.getParameterMap();Set set = keys.entrySet();Iterator iters = set.iterator();while (iters.hasNext()) {Object key = iters.next();Object value = keys.get(key);keys.put(key, filterDangerString((String[]) value));}return keys;}/*@Overridepublic Object getAttribute(String name) {// TODO Auto-generated method stubObject object = super.getAttribute(name);if (object instanceof String) {return filterDangerString((String) super.getAttribute(name));} elsereturn object;}*/public String filterDangerString(String value) {if (value == null) {return null;}//value = value.replaceAll('{', '{');value = value.replaceAll('<', '<');value = value.replaceAll('>', '>');//value = value.replaceAll('t', ' ');//value = value.replaceAll('rn', 'n');//value = value.replaceAll('n', '<br/>');//value = value.replaceAll('’', ''');//value = value.replaceAll('', '\');//value = value.replaceAll(''', '"');//value = value.replaceAll('}', '?').trim();return value;}public String[] filterDangerString(String[] value) {if (value == null) {return null;}for (int i = 0; i < value.length; i++) {String val = filterDangerString(value[i]);value[i] = val;}return value;}}
web.xm中的过滤器配置:
<filter> <filter-name>StringFilter</filter-name> <filter-class>com.xxx.base.filter.StringFilter</filter-class> </filter> <filter-mapping> <filter-name>StringFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>2.解决方法二(转,未验证)2.1前端过滤
2.1.1 javascript 原生方法
//转义 元素的innerHTML内容即为转义后的字符 function htmlEncode ( str ) { var ele = document.createElement(’span’); ele.appendChild( document.createTextNode( str ) ); return ele.innerHTML; } //解析 function htmlDecode ( str ) { var ele = document.createElement(’span’); ele.innerHTML = str; return ele.textContent; }
2.1.2 JQuery 方法
function htmlEncodeJQ ( str ) { return $(’<span/>’).text( str ).html(); } function htmlDecodeJQ ( str ) { return $(’<span/>’).html( str ).text(); }
2.1.3 调用方法
var msg1= htmlEncodeJQ(’<script>alert(’test’);</script>’);var msg1= htmlEncode(’<script>alert(’test’);</script>’);//结果变成:<script>alert(’test’);</script>2.2 后端过滤
2.2.1 java 一些框架自动工具类,
比如:org.springframework.web.util.HtmlUtils
public static void main(String[] args) { String content = '<script>alert(’test’);</script>'; System.out.println('content='+content); content = HtmlUtils.htmlEscape(content); System.out.println('content='+content); content = HtmlUtils.htmlUnescape(content); System.out.println('content='+content);}
但这样有个问题,就是它全部的html标签都不解析了。
可能这不是你想要的,你想要的是一部分解析,一部分不解析。好看下面。
2.2.2 自己用正则来完成你的需求
package top.lrshuai.blog.util;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * * @author lrshuai * @since 2017-10-13 * @version 0.0.1 */public class HTMLUtils {/** * 过滤所有HTML 标签 * @param htmlStr * @return */public static String filterHTMLTag(String htmlStr) { //定义HTML标签的正则表达式 String reg_html='<[^>]+>'; Pattern pattern=Pattern.compile(reg_html,Pattern.CASE_INSENSITIVE); Matcher matcher=pattern.matcher(htmlStr); htmlStr=matcher.replaceAll(''); //过滤html标签 return htmlStr;}/** * 过滤标签,通过标签名 * @param htmlStr * @param tagName * @return */public static String filterTagByName(String htmlStr,String tagName) { String reg_html='<'+tagName+'[^>]*?>[sS]*?</'+tagName+'>'; Pattern pattern=Pattern.compile(reg_html,Pattern.CASE_INSENSITIVE); Matcher matcher=pattern.matcher(htmlStr); htmlStr=matcher.replaceAll(''); //过滤html标签 return htmlStr;}/** * 过滤标签上的 style 样式 * @param htmlStr * @return */public static String filterHTMLTagInStyle(String htmlStr) { String reg_html='style=(’|')(.*?)(’|')'; Pattern pattern=Pattern.compile(reg_html,Pattern.CASE_INSENSITIVE); Matcher matcher=pattern.matcher(htmlStr); htmlStr=matcher.replaceAll(''); //过滤html标签 return htmlStr;}/** * 替换表情 * @param htmlStr * @param tagName * @return */public static String replayFace(String htmlStr) { String reg_html='[em_d{1,}]'; Pattern pattern =Pattern.compile(reg_html,Pattern.CASE_INSENSITIVE); Matcher matcher=pattern.matcher(htmlStr); if(matcher.find()) {matcher.reset();while(matcher.find()) { String num = matcher.group(0); String number=num.substring(num.lastIndexOf(’_’)+1, num.length()-1); htmlStr = htmlStr.replace(num, '<img src=’/face/arclist/'+number+'.gif’ border=’0’ />');} } return htmlStr;} public static void main(String[] args) {String html = '<script>alert(’test’);</script><img src=’/face/arclist/5.gif’ border=’0’ /><div style=’position:fixs;s’></div><style>body{color:#fff;}</style><Style>body{color:#fff;}</Style><STYLE>body{color:#fff;}</STYLE>';System.out.println('html='+html);html = HTMLUtils.filterTagByName(html, 'style');System.out.println('html='+html);html = HTMLUtils.filterTagByName(html, 'script');System.out.println('html='+html);html = HTMLUtils.filterHTMLTagInStyle(html);System.out.println('html='+html); }}java 过滤特殊字符串升级版
ASCII码中除了32之外还有160这个特殊的空格 db中的空格 不间断空格->页面上的 所产生的空格;
/** * 过滤特殊字符 * @param str * @return * * u00A0 特殊的空格 */ public static String stringFilter (String str){String regEx='[u00A0s'`~!@#$%^&*()+=|{}’:;’,[].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]';Pattern p = Pattern.compile(regEx);Matcher m = p.matcher(str);return m.replaceAll('').trim(); }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持好吧啦网。
相关文章: