前言:SpringBoot防XSS攻击,这几天自己学习了一下SpringBoot项目怎防Xss攻击,这里记录一下怎么防止Xss攻击的代码,等以后有需要用到的话,自己可以快速找到
1. 什么是 XSS 漏洞?
XSS 攻击:跨站脚本攻击(Cross Site Scripting),为不和 前端层叠样式表(Cascading Style Sheets)CSS 混淆,故将跨站脚本攻击缩写为 XSS。
XSS(跨站脚本攻击)是指恶意攻击者往 Web 页面里插入恶意 Script 代码,当用户浏览该页时,嵌入其中 Web 里面的 Script 代码会被执行,从而达到恶意攻击用户的目的。类似于 sql 注入。是目前最普遍的 Web 应用安全漏洞,也是 Web 攻击中最常见的攻击方式之一。
XSS( 跨站脚本攻击)攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是 JavaScript,但实际上也可以包括 Java、 VBScript、ActiveX、 Flash 或者甚至是普通的 HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和 cookie 等各种内容。
2. XSS 漏洞攻击原理及攻击手段
HTML 是一种超文本标记语言,通过将一些字符特殊地对待来区别文本和标记,例如,小于符号(<)被看作是 HTML 标签的开始,之间的字符是页面的标题等等。
当动态页面中插入的内容含有这些特殊字符(如<)时,用户浏览器会将其误认为是插入了 HTML 标签,当这些 HTML 标签引入了一段 JavaScript 脚本时,这些脚本程序就将会在用户浏览器中执行。所以,当这些特殊字符不能被动态页面检查或检查出现失误时,就将会产生 XSS 漏洞。
常用的 XSS 攻击手段和目的有:
1、盗用 cookie,获取敏感信息。
2、利用植入 Flash,通过 crossdomain 权限设置进一步获取更高权限;或者利用 Java 等得到类似的操作。
3、利用 iframe、frame、XMLHttpRequest 或上述 Flash 等方式,以(被攻击)用户的身份执行一些管理动作,或执行一些一般的如发微博、加好友、发私信等操作。
4、利用可被攻击的域受到其他域信任的特点,以受信任来源的身份请求一些平时不允许的操作,如进行不当的投票活动。
5、在访问量极大的一些页面上的 XSS 可以攻击一些小型网站,实现 DDoS 攻击的效果。
最简单的 XSS 示例:
<script>alert('hello world')</script>
<script src='http://www.smart4j.cn/xxx.js'></script>
<input type="button" value="评论"></input>
3. XSS 分类如下:
分类 | 主要特点 |
---|---|
存储型 XSS | 经过后端服务处理,数据存储在数据库端 |
反射型 XSS | 经过后端服务处理,不存储数据库 |
DOM型 XSS | 不经过后端服务处理,不存储数据库 |
4. XSS 漏洞分析
4.1 存储型 XSS
通过网页注入的代码最终会存储在数据库或其他物理文件中,在某个页面中注入的代码会被浏览器成功执行,该类型的漏洞存在持久性的特点。
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
public class XssStringJsonDeserializer extends JsonDeserializer<String> {
public XssStringJsonDeserializer() {
}
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
String source = p.getText();
if (StringUtils.isNotBlank(source)) {
source = this.xssScriptReplace(source);
return source;
} else {
return source;
}
}
public String xssScriptReplace(String value) {
if (value != null) {
List<String> regexList = new ArrayList();
regexList.add("alert\\s*\\((.*?)\\)");
regexList.add("expression\\s*\\((.*?)\\)");
regexList.add("<script(\\s*)>(.*?)</script(\\s*)>");
regexList.add("<style(\\s*)>(.*?)</style(\\s*)>");
regexList.add("<applet(.*?)/>|<applet(.*?)>(.*?)</applet(\\s*)>");
regexList.add("<object(.*?)/>|<object(.*?)>(.*?)</object(\\s*)>");
regexList.add("<embed(.*?)/>|<embed(.*?)>(.*?)</embed(\\s*)>");
regexList.add("eval\\s*\\((.*?)\\)");
regexList.add("\\'javascript(\\s*):(.*?)\\'|\\\"javascript(\\s*):(.*?)\\\"");
regexList.add("\\'vbscript(\\s*):(.*?)\\'|\\\"vbscript(\\s*):(.*?)\\\"");
regexList.add("<iframe\\s+(.*?)/>|<iframe\\s+(.*?)>(.*?)</iframe(\\s*)>");
regexList.add("(\\s+)onmouseover\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onmouseover\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onmouseout\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onmouseout\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onmousedown\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onmousedown\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onmouseup\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onmouseup\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onmousemove\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onmousemove\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onclick\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onclick\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)ondblclick\\s*=(\\s*)\\'(.*?)\\'|(\\s+)ondblclick\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onkeypress\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onkeypress\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onkeydown\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onkeydown\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onkeyup\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onkeyup\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)ondragstart\\s*=(\\s*)\\'(.*?)\\'|(\\s+)ondragstart\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onerrorupdate\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onerrorupdate\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onhelp\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onhelp\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onreadystatechange\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onreadystatechange\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onrowenter\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onrowenter\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onrowexit\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onrowexit\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onselectstart\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onselectstart\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onload\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onload\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onunload\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onunload\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onbeforeunload\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onbeforeunload\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onblur\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onblur\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onerror\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onerror\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onfocus\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onfocus\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onresize\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onresize\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onscroll\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onscroll\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)oncontextmenu\\s*=(\\s*)\\'(.*?)\\'|(\\s+)oncontextmenu\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onbounce\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onbounce\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onfinish\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onfinish\\s*=(\\s*)\\\"(.*?)\\\"");
regexList.add("(\\s+)onstart\\s*=(\\s*)\\'(.*?)\\'|(\\s+)onstart\\s*=(\\s*)\\\"(.*?)\\\"");
Pattern scriptPattern;
for(Iterator var3 = regexList.iterator(); var3.hasNext(); value = scriptPattern.matcher(value).replaceAll(" ")) {
String regex = (String)var3.next();
scriptPattern = Pattern.compile(regex, 42);
}
}
return value;
}
}