XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。比如这些代码包括HTML代码和客户端脚本。攻击者利用XSS漏洞旁路掉访问控制——例如同源策略(same origin policy)。这种类型的漏洞由于被黑客用来编写危害性更大的网络钓鱼(Phishing)攻击而变得广为人知。对于跨站脚本攻击,黑客界共识是:跨站脚本攻击是新型的“缓冲区溢出攻击“,而JavaScript是新型的“ShellCode”。
回到主题:我们应该怎么解决这个问题呢?
1、创建一个工具类
StringEscapeEditor extends PropertyEditorSupport
public StringEscapeEditor() { super(); } @Override public void setAsText(String text) { String value = stripXSS(text); setValue(value); } @Override public String getAsText() { Object value = getValue(); return value != null ? value.toString() : ""; }2、然后定义stripXSS方法:
if (value == null || "".equals(value)) { return value; } value = value.trim(); //是否为忽略xss拦截 默认为false boolean xss = false; if (!value.contains("ignoreXSS")) { xss = false; } else { value = value.replaceAll("ignoreXSS", ""); xss = true; } Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<iframe>(.*?)</iframe>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); //xss放行所有a标签 if (!xss) { scriptPattern = Pattern.compile("<a>(.*?)</a>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("</a>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<a(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<a>(.*?)</a>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("</a>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<a(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); } scriptPattern = Pattern.compile("<link>(.*?)</link>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<style>(.*?)</style>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("</iframe>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("</link>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("</style>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<iframe(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<link(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<style(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<iframe>(.*?)</iframe>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<link>(.*?)</link>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<style>(.*?)</style>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("</iframe>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("</link>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("</style>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<iframe(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<link(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<style(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); 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 actionscript:... expressions scriptPattern = Pattern.compile("actionscript:", 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(""); //转义字符 value = value.replaceAll("&", "&"); value = value.replaceAll("<", "<"); value = value.replaceAll(">", ">"); value = value.replaceAll("\"", """); value = value.replaceAll("'", ""); return value;
在stripXSS处理后,return处理过的参数,再放行到controller中。
那controller如何调用此方法呢?
@InitBinder protected void initBinder(WebDataBinder binder) { binder.registerCustomEditor(String.class, new StringEscapeEditor()); }大功告成,快去试试吧!