# 跨站请求伪造(CSRF,Cross Site request forgery),也称为XSRF
# 概念
- 攻击者利用技术手段欺骗用户的浏览器去访问曾经认证过的网站,并触发一些操作
- 由于浏览器曾经认证过,所以被访问的网站,会认为是真正的用户操作而去运行
# 本质
- 攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说,这个请求是完全合理合法的,但是却完成了攻击者所期望的操作。
- 有两个关键点,一,用户需要知道你的业务接口,二,浏览器主流方案通过cookie实现会话机制
# 解决方案-CSRF防护
- 每个session需要有一个与之相绑定的CSRF-TOKEN
- 理论上来说,这个CSRF-TOKEN的存储不应该使用浏览器的cookie机制,但某框架并没有遵循这个原则;
# springSecurity的CsrfFilter
- 该过滤器允许配置白名单
- 该过滤器要求,白名单外的每个访问链接都必须具有cookie,否则不允许放行
- 该过滤器默认情况下,先于AbstractAuthenticationProcessingFilter、FilterSecurityInterceptor生效
# 跨站脚本攻击(XSS,Cross Site Scripting)
# 概念
- 本应该缩写为CSS,为了与层叠样式表区分,故取为XSS
- 此类攻击的核心为 脚本
# 分类
- 反射型XSS攻击
- 通过特定手法,诱导用户去点击含有恶意代码的URL
- 常用来窃取客户端cookie以及 钓鱼欺骗
- DOM-based型XSS攻击
- 客户端的脚本程序,可以动态的检查和修改页面内容,而不依赖服务端的数据
- 如富文本输入,并预览;
- 存储型XSS攻击
- 攻击者事先将恶意代码上传,或储存到漏洞服务器中
- 受害者浏览包含恶意代码的页面,就会执行恶意代码
# 防护(主要针对存储型XSS攻击)
- 转码
- 程序层面 (StringUtils.htmlEscape,StringUtils.htmlUnescape)
- 基础设施层面 Filer将所有的半码字符转为全码字符
- 替换
- 通过Filter,替换关键字
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author automannn
* @Date 2022/6/23
*/
public class XssCleanUtil {
private static List<Pattern> patterns = null;
private static List<Object[]> getXssPatternList() {
List<Object[]> ret = new ArrayList();
ret.add(new Object[]{"<(no)?script[^>]*>.*?</(no)?script>", 2});
ret.add(new Object[]{"eval\\((.*?)\\)", 42});
ret.add(new Object[]{"expression\\((.*?)\\)", 42});
ret.add(new Object[]{"(javascript:|vbscript:|view-source:)*", 2});
ret.add(new Object[]{"(window\\.location|window\\.|\\.location|document\\.cookie|document\\.|alert\\(.*?\\)|window\\.open\\()*", 42});
ret.add(new Object[]{"<+\\s*\\w*\\s*.*\\s*(oncontrolselect|oncopy|oncut|ondataavailable|ondatasetchanged|ondatasetcomplete|ondblclick|ondeactivate|ondrag|ondragend|ondragenter|ondragleave|ondragover|ondragstart|ondrop|onerror|onerroupdate|onfilterchange|onfinish|onfocus|onfocusin|onfocusout|onhelp|onkeydown|onkeypress|onkeyup|onlayoutcomplete|onload|onlosecapture|onmousedown|onmouseenter|onmouseleave|onmousemove|onmousout|onmouseover|onmouseup|onmousewheel|onmove|onmoveend|onmovestart|onabort|onactivate|onafterprint|onafterupdate|onbefore|onbeforeactivate|onbeforecopy|onbeforecut|onbeforedeactivate|onbeforeeditocus|onbeforepaste|onbeforeprint|onbeforeunload|onbeforeupdate|onblur|onbounce|oncellchange|onchange|onclick|oncontextmenu|onpaste|onpropertychange|onreadystatechange|onreset|onresize|onresizend|onresizestart|onrowenter|onrowexit|onrowsdelete|onrowsinserted|onscroll|onselect|onselectionchange|onselectstart|onstart|onstop|onsubmit|onunload|ontoggle|onshow|onbeforeonload|onhashchange|onmessage|onoffline|ononline|onpagehide|onpageshow|onpopstate|onredo|onstorage|onundo|onformchange|onforminput|oninput|oninvalid|oncanplay|oncanplaythrough|ondurationchange|onemptied|onended|onloadeddata|onloadedmetadata|onloadstart|onpause|onplay|onplaying|onprogress|onratechange|onseeked|onseeking|onstalled|onsuspend|ontimeupdate|onvolumechange|onwaiting)+\\s*=+", 42});
return ret;
}
private static List<Pattern> getPatterns() {
if (patterns == null) {
List<Pattern> list = new ArrayList();
Iterator var4 = getXssPatternList().iterator();
while (var4.hasNext()) {
Object[] arr = (Object[]) var4.next();
String regex = (String) arr[0];
Integer flag = (Integer) arr[1];
list.add(Pattern.compile(regex, flag));
}
patterns = list;
}
return patterns;
}
public static String stripXss(String value) {
if (StringUtils.isNotBlank(value)) {
Iterator var2 = getPatterns().iterator();
while (var2.hasNext()) {
Pattern pattern = (Pattern) var2.next();
Matcher matcher = pattern.matcher(value);
if (matcher.find()) {
value = matcher.replaceAll("");
}
}
}
return value;
}
public static String clean(String originalContent) {
String target = stripXss(originalContent);
return target;
}
}
# 跨域
# 同源
- 同源指的是:协议,域名,端口相同
- 浏览器出于安全方面的考虑,只允许本域名下的接口交互,不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的资源
# 同源的分类
- DOM同源策略: 禁止对不同源页面DOM进行操作。主要针对iframe
- XHR同源策略: 禁止使用XHR对象,向不同源的服务器地址发起HTTP请求
# 同源策略造成的影响
- Cookie、LocalStorage 和 IndexDB无法读取
- DOM和JS对象无法获取
- Ajax请求发送不出去
# 跨域的类型
- 协议型跨域
- 域名型跨域
- 端口型跨域
# 跨域资源共享(Cross-Origin Resource Sharing)
# 概念
- 它是由浏览器的同源策略造成的,是对 javaScript实施的安全限制
- 一种允许当前域的资源被其他域的脚本请求访问的机制
# 何时触发跨域检查
- Cors将请求分为简答请求与复杂请求
- 简单请求满足的条件:
- 使用方法为 GET、HEAD、POST
- Content-Type的值为: text/plain、multipart/form-data、application/x-www-form-urlencoded
- 不符合简单请求条件的便是复杂请求,复杂请求正式通信前,会进行cors预检
# springWeb的CorsFilter
- springSecurity对其进行了原生支持
- 可以通过参数的方式,指定allowed-origins、allowed-header、allowed-method
- cors可配置白名单(理论上,所有基于Filter的功能都可配置白名单)
# 跨站
# 概念
- 两个地址的**
eTLD+1
不同,则为跨站** - eTLD 为 effective top-level domain,有效顶级域名,如:
.com
,.cn
,.top
等等 - eTLD+1为顶级域名+二级域名,如:
.cn
与automannn.cn
# 跨站与跨域的区别
- 跨域分为三类:协议跨域,主机跨域,端口跨域
- 跨站只考虑主机段(如果是ip的话),不考虑协议和端口