AntiXSSUtil.java
5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package com.xkl.security;
import org.apache.oro.text.regex.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 防XSS攻击
* <p>
* Created by win7 on 2016/10/21.
*/
public class AntiXSSUtil {
static final Pattern SCRIPT_TAG_PATTERN = Pattern.compile("<script[^>]*>.*</script[^>]*>", Pattern.CASE_INSENSITIVE);
static final PatternCompiler pc = new Perl5Compiler();
static final PatternMatcher matcher = new Perl5Matcher();
public static String antiXSS(String content) {
if (content == null || content.equals("")) {
return "";
}
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("");
return content;
}
private static String stripEvent(String content) throws Exception {
String[] events = {
"onmouseover", "onmouseout", "onmousedown", "onmouseup",
"onmousemove", "onclick", "ondblclick", "onkeypress", "onkeydown",
"onkeyup", "ondragstart", "onerrorupdate", "onhelp",
"onreadystatechange", "onrowenter", "onrowexit", "onselectstart",
"onload", "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);
}
return content;
}
private static String stripAsciiAndHex(String content) throws Exception {
// filter &# \00xx
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;
}
}