XSS又称CSS,全称Cross SiteScript,跨站脚本攻击,是Web程序中常见的漏洞,XSS属于被动式且用于客户端的攻击方式,所以容易被忽略其危害性。其原理是攻击者向有XSS漏洞的网站中输入(传入)恶意的HTML代码,当其它用户浏览该网站时,这段HTML代码会自动执行,从而达到攻击的目的。如,盗取用户Cookie、破坏页面结构、重定向到其它网站等。
java防止XSS攻击的常用方法总结。
1.自己写过滤器拦截来实现,但要注意的时间,在WEB.XML中配置过滤器的时候,请将这个过滤器放在第一位。
2.采用开源的实现ESAPI库,
3.可以采用弹簧里面提供的工具类来实现。
一,第一种方法。
配置过滤器
public class XSSFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
}}
再实现ServletRequest的包装类
import java.util.regex.Pattern;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;public class XSSRequestWrapper extends HttpServletRequestWrapper {
public XSSRequestWrapper(HttpServletRequest servletRequest) {
super(servletRequest);
}
@Override
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] = stripXSS(values[i]);
}
return encodedValues;
}
@Override
public String getParameter(String parameter) {
String value = super.getParameter(parameter);
return stripXSS(value);
}
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
return stripXSS(value);
}
private String stripXSS(String value) {
if (value != null) {
// NOTE: It’s highly recommended to use the ESAPI library and uncomment the following line to
// avoid encoded attacks.
// value = ESAPI.encoder().canonicalize(value);
// Avoid null characters
value = value.replaceAll(“”, “”);
// Avoid anything between script tags
Pattern scriptPattern = Pattern.compile(“<script>(.*?)</script>”, Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll(“”);
// Avoid anything in a src=”http://www.trustauth.cn/article/java/…” type of expression
scriptPattern = Pattern.compile(“src[\r\n]*=[\r\n]*\\\'(.*?)\\\'”, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll(“”);
scriptPattern = Pattern.compile(“src[\r\n]*=[\r\n]*\\\”(.*?)\\\””, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll(“”);
// Remove any lonesome </script> tag
scriptPattern = Pattern.compile(“</script>”, Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll(“”);
// Remove any lonesome <script …> tag
scriptPattern = Pattern.compile(“<script(.*?)>”, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll(“”);
// Avoid eval(…) expressions
scriptPattern = Pattern.compile(“eval\\((.*?)\\)”, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll(“”);
// Avoid expression(…) expressions
scriptPattern = Pattern.compile(“expression\\((.*?)\\)”, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll(“”);
// Avoid javascript:… expressions
scriptPattern = Pattern.compile(“javascript:”, Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll(“”);
// Avoid vbscript:… expressions
scriptPattern = Pattern.compile(“vbscript:”, Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll(“”);
// Avoid onload= expressions
scriptPattern = Pattern.compile(“onload(.*?)=”, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll(“”);
}
return value;
}}
例子中注释的部分,就是采用ESAPI库来防止XSS攻击的,推荐使用。
当然,我还看到这样一种办法,将所有的编程全角字符的解决方式,但个人觉得并没有上面这种用正则表达式替换的好
private static String xssEncode(String s) {
if (s == null || s.equals(“”)) {
return s;
}
StringBuilder sb = new StringBuilder(s.length() + 16);
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
switch (c) {
case ‘>’:
sb.append(‘>’);// 全角大于号
break;
case ‘<‘:
sb.append(‘<’);// 全角小于号
break;
case ‘\”:
sb.append(‘\\’);
sb.append(‘\”);
sb.append(‘\\’);
sb.append(‘\”);
break;
case ‘\”‘:
sb.append(‘\\’);
sb.append(‘\”‘);// 全角双引号
break;
case ‘&’:
sb.append(‘&’);// 全角
break;
case ‘\\’:
sb.append(‘\’);// 全角斜线
break;
case ‘#’:
sb.append(‘#’);// 全角井号
break;
case ‘:’:
sb.append(‘:’);// 全角冒号
break;
case ‘%’:
sb.append(“\\\\%”);
break;
default:
sb.append(c);
break;
}
}
return sb.toString();
}
当然,还有如下更简单的方式:
private String cleanXSS(String value) {
//You’ll need to remove the spaces from the html entities below
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;
}
在后台或者用spring如何实现呢:
首先添加一个jar包:commons-lang-2.5.jar,然后在后台调用这些函数:
StringEscapeUtils.escapeHtml(string); StringEscapeUtils.escapeJavaScript(string); StringEscapeUtils.escapeSql(string);
当然,我记得在春天里面好像有一个HtmlUtils.htmlEscape,同样可以做到过滤XSS攻击。
HTML标签防XSS攻击过滤
通过标签白名单及属性白名单来过滤HTML标签,同时对包含特殊字符的属性值进行处理。默认配置可过滤大多数的XSS攻击代码,可根据实际应用场景来定制白名单及过滤方法。
载入模块
var xss = require(‘xss’);
使用默认的配置
var html = xss(‘<script>alert(“xss”);</script>’);
console.log(html);
修改默认配置
// 添加或更新白名单中的标签 标签名(小写) = [‘允许的属性列表(小写)’]
xss.whiteList[‘p’] = [‘class’, ‘style’];
// 删除默认的白名单标签
delete xss.whiteList[‘div’];
// 自定义处理属性值函数
xss.onTagAttr = function (tag, attr, vaule) {
// tag:当前标签名(小写)
// attr:当前属性名(小写)
// value:当前属性值
// 返回新的属性值,如果想使用默认的处理方式,不返回任何值即可
// 比如把属性值中的双引号替换为"e;:return value.replace(/”/g, ‘"e;’);
// 以下为默认的处理代码:
if (attr === ‘href’ || attr === ‘src’) {
if (/\/\*|\*\//mg.test(value)) {
return ‘#’;
}
if (/^[\s”‘`]*((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a):/ig.test(value)) {
return ‘#’;
}
} else if (attr === ‘style’) {
if (/\/\*|\*\//mg.test(value)) {
return ‘#’;
}
if (/((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a):/ig.test(value)) {
return ”;
}
}
};
// 自定义处理不在白名单中的标签
xss.onIgnoreTag = function (tag, html) {
// tag:当前标签名(小写),如:a
// html:当前标签的HTML代码,如:<a href=”ooxx”>
// 返回新的标签HTML代码,如果想使用默认的处理方式,不返回任何值即可
// 比如将标签替换为[removed]:return ‘[removed]’;
// 以下为默认的处理代码:
return html.replace(/</g, ‘<‘).replace(/>/g, ‘>’);
}
使用临时配置
var options = {
whiteList: {}, // 若不指定则使用默认配置,可参考xss.whiteList
onTagAttr: function () {}, // 若不指定则使用默认配置,可参考xss.onTagAttr
onIgnoreTag: function () {} // 若不指定则使用默认配置,可参考xss.onIgnoreTag
};
var html = xss(‘<script>alert(“xss”);</script>’, options);
console.log(html);
单元测试
在源码目录执行命令:npm test
在线测试
在源码目录执行命令:node cli.js,可在命令行中输入HTML代码,并看到过滤后的代码
性能
解析速度为5.81MB/s,而另外一个validator模块的xss()函数速度仅为2.48MB/s。
SSL证书是HTTP明文协议升级HTTPS加密协议的重要渠道,是网络安全传输的加密到通道。关于更多SSL证书的资讯,请关注GDCA(数安时代)。GDCA致力于网络信息安全,已通过WebTrust 的国际认证,是全球可信任的证书签发机构。GDCA专业技术团队将根据用户具体情况为其提供最优的产品选择建议,并针对不同的应用或服务器要求提供专业对应的HTTPS解决方案。
上一篇:Java语言加密工具Jasypt
下一篇:JavaScript常见缩写代码