antixss.java
来自「cwbbs 云网论坛源码」· Java 代码 · 共 265 行
JAVA
265 行
package cn.js.fan.security;import java.util.regex.Matcher;import java.util.regex.Pattern;import org.apache.oro.text.regex.PatternCompiler;import org.apache.oro.text.regex.PatternMatcher;import org.apache.oro.text.regex.Perl5Compiler;import org.apache.oro.text.regex.Perl5Matcher;import org.apache.oro.text.regex.Perl5Substitution;import org.apache.oro.text.regex.Util;public class AntiXSS { static final Pattern SCRIPT_TAG_PATTERN = Pattern.compile( "<script[^>]*>.*</script[^>]*>", Pattern.CASE_INSENSITIVE); static final Pattern IFRAME_TAG_PATTERN = Pattern.compile( "<iframe[^>]*>.*</iframe[^>]*>", Pattern.CASE_INSENSITIVE); static final PatternCompiler pc = new Perl5Compiler(); static final PatternMatcher matcher = new Perl5Matcher(); public static String antiXSS(String content) { String old = content; String ret = _antiXSS(content); while (!ret.equals(old)) { old = ret; ret = _antiXSS(ret); } return ret; } private static String _antiXSS(String content) { try { return stripAllowScriptAccess(stripProtocol(stripCssExpression( stripAsciiAndHex(stripEvent(stripScriptTag(content)))))); } catch (Exception e) { e.printStackTrace(); return null; } } private static String stripScriptTag(String content) { Matcher m = SCRIPT_TAG_PATTERN.matcher(content); content = m.replaceAll(""); m = IFRAME_TAG_PATTERN.matcher(content); content = m.replaceAll(""); return content; } private static String stripEvent(String content) throws Exception { String[] events = {"onmouseover", "onmouseout", "onmousedown", "onmouseup", "onmousemove", "ondblclick", "onkeypress", "onkeydown", "onkeyup", "ondragstart", "onerrorupdate", "onhelp", "onreadystatechange", "onrowenter", "onrowexit", "onselectstart", "onunload", "onbeforeunload", "onblur", "onerror", "onfocus", "onresize", "onscroll", "oncontextmenu",}; for (String event : events) { org.apache.oro.text.regex.Pattern p = pc.compile("(<[^>]*)(" + event + ")([^>]*>)", Perl5Compiler.CASE_INSENSITIVE_MASK); if (null != p) { content = Util.substitute(matcher, p, new Perl5Substitution( "$1" + event.substring(2) + "$3"), content, Util.SUBSTITUTE_ALL); } } String patternStr = "(<[^>]*?)onload=([\"|'](.+?)[\"|'])"; java.util.regex.Pattern pattern = java.util.regex.Pattern.compile( patternStr, Pattern.DOTALL | Pattern.CASE_INSENSITIVE); java.util.regex.Matcher mat = pattern.matcher(content); StringBuffer sb = new StringBuffer(); boolean result = mat.find(); boolean isFind = false; while (result) { String tagStr = mat.group(0); boolean isValid = true; if (!tagStr.substring(1, 4).equalsIgnoreCase("img")) { isValid = false; } else { String onloadStr = mat.group(3).toLowerCase(); if (onloadStr.indexOf("location")!=-1 || onloadStr.indexOf("open")!=-1) { isValid = false; } } if (!isValid) { String str = "$1load=$2"; mat.appendReplacement(sb, str); mat.appendTail(sb); isFind = true; } result = mat.find(); } if (isFind) { content = sb.toString(); } patternStr = "(<[^>]*)onclick=(\"(.*?)\".*?>)"; pattern = java.util.regex.Pattern.compile( patternStr, Pattern.DOTALL | Pattern.CASE_INSENSITIVE); mat = pattern.matcher(content); sb = new StringBuffer(); result = mat.find(); isFind = false; while (result) { String imgTag = mat.group(0); if (!imgTag.substring(1, 4).equalsIgnoreCase("img")) { String str = "$1click=$2"; mat.appendReplacement(sb, str); isFind = true; } else { boolean isValid = true; String imgOnClick = mat.group(3).toLowerCase(); if (imgOnClick.indexOf("location")!=-1) { isValid = false; } if (isValid) { if (imgOnClick.indexOf("open") != -1) { boolean isSrcEqualsOpenParam = false; String patString = "<img.*?src.*?=\\s*?([^> ]+)\\s*.*?>"; java.util.regex.Pattern pat = java.util.regex.Pattern. compile(patString, Pattern.DOTALL | Pattern.CASE_INSENSITIVE); Matcher m = pat.matcher(imgTag); if (m.find()) { String imgUrl = m.group(1).replaceAll("\"|'", ""); System.out.println("imgUrl=" + imgUrl); patString = "(<img.*?open\\s*?\\()([^> ]+)(\\)\\s*.*?>)"; pat = java.util.regex.Pattern. compile(patString, Pattern.DOTALL | Pattern.CASE_INSENSITIVE); m = pat.matcher(imgTag); if (m.find()) { String param = m.group(2).replaceAll("\"|'", ""); if (imgUrl.indexOf(param)!=-1) { isSrcEqualsOpenParam = true; } } } if (!isSrcEqualsOpenParam) { isValid = false; } } } if (!isValid) { String str = "$1click=$2"; mat.appendReplacement(sb, str); mat.appendTail(sb); isFind = true; } } result = mat.find(); } if (isFind) { content = sb.toString(); } return content; } private static String stripAsciiAndHex(String content) throws Exception { org.apache.oro.text.regex.Pattern p = pc.compile( "(<[^>]*)(&#|\\\\00)([^>]*>)", Perl5Compiler.CASE_INSENSITIVE_MASK); if (null != p) content = Util .substitute(matcher, p, new Perl5Substitution("$1$3"), content, Util.SUBSTITUTE_ALL); return content; } private static String stripCssExpression(String content) throws Exception { org.apache.oro.text.regex.Pattern p = pc.compile( "(<[^>]*style=.*)/\\*.*\\*/([^>]*>)", Perl5Compiler.CASE_INSENSITIVE_MASK); if (null != p) content = Util .substitute(matcher, p, new Perl5Substitution("$1$2"), content, Util.SUBSTITUTE_ALL); p = pc .compile( "(<[^>]*style=[^>]+)(expression|javascript|vbscript|-moz-binding)([^>]*>)", Perl5Compiler.CASE_INSENSITIVE_MASK); if (null != p) content = Util .substitute(matcher, p, new Perl5Substitution("$1$3"), content, Util.SUBSTITUTE_ALL); p = pc.compile("(<style[^>]*>.*)/\\*.*\\*/(.*</style[^>]*>)", Perl5Compiler.CASE_INSENSITIVE_MASK); if (null != p) content = Util .substitute(matcher, p, new Perl5Substitution("$1$2"), content, Util.SUBSTITUTE_ALL); p = pc .compile( "(<style[^>]*>[^>]+)(expression|javascript|vbscript|-moz-binding)(.*</style[^>]*>)", Perl5Compiler.CASE_INSENSITIVE_MASK); if (null != p) content = Util .substitute(matcher, p, new Perl5Substitution("$1$3"), content, Util.SUBSTITUTE_ALL); return content; } private static String stripProtocol(String content) throws Exception { String[] protocols = {"javascript", "vbscript", "livescript", "ms-its", "mhtml", "data", "firefoxurl", "mocha"}; for (String protocol : protocols) { org.apache.oro.text.regex.Pattern p = pc.compile("(<[^>]*)" + protocol + ":([^>]*>)", Perl5Compiler.CASE_INSENSITIVE_MASK); if (null != p) content = Util.substitute(matcher, p, new Perl5Substitution( "$1/$2"), content, Util.SUBSTITUTE_ALL); } return content; } private static String stripAllowScriptAccess(String content) throws Exception { org.apache.oro.text.regex.Pattern p = pc.compile( "(<[^>]*)AllowScriptAccess([^>]*>)", Perl5Compiler.CASE_INSENSITIVE_MASK); if (null != p) content = Util.substitute(matcher, p, new Perl5Substitution( "$1Allow_Script_Access$2"), content, Util.SUBSTITUTE_ALL); return content; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?