前端安全
1. XSS跨站脚本攻击
1.1 定义
XSS跨站脚本攻击(Cross Site Scripting),很多人会缩写成CSS,但是这个缩写会与层叠样式表(Cascading Style Sheets,CSS)的缩写混淆,所以,我们通常把跨站脚本攻击缩写成XSS;
XSS(Cross Site Scripting), 是一种网站应用程序的安全漏洞攻击 。XSS攻击通常指的是 通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。
1.2 分类
从攻击代码的工作方式看,主要分为三个类型:
-
非持久型跨站:反射型跨站脚本漏洞,是最普遍的类型。用户访问服务器-跨站链接-返回跨站代码。经过后端,不经过数据库;
这种方式下,通常出现在搜索功能中,需要攻击者点击相应的URL(恶意链接)才能触发;
-
持久性跨站:最直接的危害类型,跨站代码存储在服务器(数据库)。经过后端,经过数据库。
存储型(或 HTML 注入型/持久型)XSS 攻击最常发生在由社区内容驱动的网站或 Web 邮件网站,不需要特制的链接来执行。黑客仅仅需要提交 XSS 漏洞利用代码(反射型XSS通常只在url中)到一个网站上其他用户可能访问的地方。这些地区可能是博客评论,用户评论,留言板,聊天室,HTML 电子邮件,wikis,和其他的许多地方。
-
DOM跨站(DOM XSS):DOM(document object model文档对象模型),客户端脚本处理逻辑导致的安全问题。
通过修改页面的DOM节点形成的XSS,称之为DOM Based XSS。
攻击案例
:在这段代码中,submit按钮的onclick事件调用了xsstest()函数。而在xsstest()中,修改了页面的DOM节点,通过innerHTML把一段用户数据当作HTML写入到页面中,造成了DOM Based XSS。
<html>
<head>
<title>DOM Based XSS Demo</title>
<script>
function xsstest() {
var str = document.getElementById("input").value;
document.getElementById("output").innerHTML = "<img
src='"+str+"'></img>";
}
</script>
</head>
<body>
<div id="output"></div>
<input type="text" id="input" size=50 value="" />
<input type="button" value="submit" onclick="xsstest()" />
</body>
</html>
DOM型 XSS跟前两种XSS的区别:DOM型 XSS攻击中,取出和执⾏恶意代码由浏览器端完成,属于前端 JavaScript⾃⾝的安全漏洞,⽽其他两种 XSS都属于服务端的安全漏洞。
1.4 防御方法
-
服务器对脚本进行过滤或转码;(这一步属于后端的操作,spring函数中有专门的过滤函数)
-
利⽤CSP:其核心思想十分简单:网站通过发送一个 CSP 头部,来告诉浏览器什么是被授权执行的与什么是需要被禁止的。其被誉为专门为解决
XSS攻击
而生的神器。
可以在html中的meta中进行配置:<meta http-equiv="content-security-policy" content="策略"> <meta http-equiv="content-security-policy-report-only" content="策略">
常见的CSP指令:
-
HttpOnly
这个其实就是set-Cookie的字段,之前在讲解cookie的时候有提及过,具体可以看我之前写的这篇文章:
一篇文章搞懂缓存机制,cookie和浏览器缓存~
如果HTTP响应头中包含HttpOnly标志,只要浏览器支持HttpOnly标志,客户端脚本就无法访问cookie。
2.CSRF-跨站伪造请求(钓鱼)
2.1 定义
CSRF(Cross-site request forgery,跨站请求伪造也被称为One Click Attack 或者 Session Riding ,通常缩写为 CSRF或者XSRF,是一种欺骗受害者提交恶意请求的攻击。它继承了受害者的身份和特权,代表受害者执行非本意、恶意的操作。它强制终端用户在当前对其进行身份验证后的Web应用程序上执行非本意的操作。
与XSS对比:
尽管CSRF听起来像跨站脚本XSS,但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装成受信任用户请求受信任的网站 。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)也难以防范,所以被认为比XSS更具危险性。
点击链接后,可能发⽣3件事
- ⾃动发送GET请求。利⽤src发送请求
- ⾃动发送POST请求
- 诱导点击发送GET请求
下面具体举个例子说明什么是CSRF攻击:
举例来说,用户登陆了银行网站your-bank.com
,银行服务器发来了一个 Cookie
。
Set-Cookie:id=a3fWa;
用户后来又访问了恶意网站malicious.com
,上面有一个表单。
<form action="your-bank.com/transfer" method="POST">
...
</form>
用户一旦被诱骗发送这个表单,银行网站就会收到带有正确 Cookie 的请求。银行网站就会误以为这就是用户主动登陆的。
2.2 防范
2.2.1 SameSite
这个字段和上面讲XSS攻击的HTTPOnly一样;
SameSite
可以设置为三个值,Strict
、Lax
和None
。
- 在
Strict
模式下,浏览器完全禁⽌第三⽅请求携带Cookie。⽐如请求sanyuan.com⽹站只
能在sanyuan.com域名当中请求才能携带 Cookie,在其他⽹站请求都不能。 - 在
Lax
模式,宽松⼀点,但是只能在 get ⽅法提交表单况或者a 标签发送 get 请求的情况
下可以携带 Cookie,其他情况均不能。 - 在
None
模式下,也就是默认模式,请求会⾃动携带上 Cookie。
2.2.2 验证来源站点
请求头中的origin和referer
发送一个请求时,Request Headers(请求头)中会包含很多字段,我们来看一下请求头中的origin、referer、host的含义和区别。
我们先看一下请求头中包含这几个字段的情形。
Origin表示当前请求资源所在页面的协议和域名,用来说明请求从哪里发起的,如http://test.my.com,
特别注意:
这个参数一般只存在于CORS跨域请求中,普通请求没有这个header!
如果有Origin参数,我们可以看到response有对应的header:Access-Control-Allow-Origin
Referer表示当前请求资源所在页面的完整路径:协议+域名+查询参数(注意不包含锚点信息),如http://test.my.com/p/GHB2021081702-001/index.html?a=1&b=2,所有类型的请求都包含此header。
2.2.3 CSRF Roken
利⽤token(后端⽣成的⼀个唯⼀登陆态,传给前端保存)每次前端请求都会带token,后
端检验通过才同意请求。
- 敏感操作需要确认
- 敏感信息的cookie只能有较短的⽣命周期
2.2.4 安全框架
如Spring Security。
参考文献
[1] 一篇文章搞懂缓存机制,cookie和浏览器缓存~
[2] XSS跨站脚本攻击详解(包括攻击方式和防御方式)
[3] 内容安全策略(CSP)详解
[4] 代码随想录前端八股文
[5] http请求头中的origin、referer、host