前端安全
XSS攻击 跨站脚本攻击
是什么
XSS(Cross-Site Scripting)跨站脚本攻击是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,当用户浏览该页面,恶意脚本被执行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie 等,进而危害数据安全。
XSS攻击的本质是:恶意代码未经过滤,浏览器无法分辨哪些脚本是可信的,导致恶意脚本被执行。
XSS攻击分类
类型 | 存储区:恶意代码存放的位置 | 插入点:由谁取得恶意代码,并插入到网页上 | 特点 |
---|---|---|---|
存储型XSS | 后端数据库 | HTML | 服务器取出恶意代码,拼接在HTML中返回给浏览器,浏览器执行,属于服务端的安全漏洞。 |
反射型XSS | URL | HTML | 服务器取出恶意代码,拼接在HTML中返回给浏览器,浏览器执行,属于服务端的安全漏洞。 |
DOM型XSS | 通过恶意脚本修改页面的 DOM 结构 | 前端 JavaScript | 取出和执行恶意代码由浏览器端完成,属于JavaScript自身的安全漏洞。 |
存储型XSS的攻击步骤
比较常见的一个场景是攻击者在社区或论坛上写下一篇包含恶意 JavaScript 代码的文章或评论,文章或评论发表后,所有访问该文章或评论的用户,都会在他们的浏览器中执行这段恶意的 JavaScript 代码
反射型XSS的攻击步骤
- 攻击者构造出特殊的 URL,其中包含恶意代码。
- 用户打开带有恶意代码的 URL 时,网站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器。
- 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
- 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。
需要用户主动打开恶意的 URL 才能生效,攻击者往往会结合多种手段诱导用户点击。
DOM型XSS攻击
XSS的防御
三种XSS类型的共性是最终浏览器执行恶意代码,那么可以通过防止浏览器执行恶意代码
来防范XSS
预防存储型和反射型 XSS 攻击
存储型和反射型 XSS 都是在服务端取出恶意代码后,插入到响应 HTML 里的,被浏览器所执行。
常见的两种预防做法
- 改成纯前端渲染(服务器渲染是将数据拼接好之后返回HTML页面给前端)
- 对 HTML 做充分转义,如果必须要拼接HTML
DOM 型 XSS 攻击
本质是:前端 JavaScript 代码本身不够严谨,把不可信的数据当作代码执行了。
- 避免前端直接拼接HTML到页面上,用
createElement
、setAttribute
之类的方法代替实现 - 用户输入过滤
其他安全措施
HttpOnly Cookie
: 禁止页面的JavaScript 读取带有 HttpOnly 属性的Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie。内容安全策略(Content Security Policy CSP)
:白名单制度,对于显示富文本来说,不能通过上面的办法来转义所有字符,因为这样会把需要的格式也过滤掉。这种情况通常采用白名单过滤的办法。开发者明确告诉客户端,哪些外部资源可以加载和执行,大大增强了网页的安全性。
可以通过两种方法启动CSP
1.通过 HTTP 头信息的 Content-Security-Policy 的字段:
Content-Security-Policy: script-src 'self';
object-src 'none';
style-src cdn.example.org third-party.org;
child-src https:
2.通过网页的<meta>
标签
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">
- 脚本: 只信任当前域名
<object>
标签: 不信任任何 URL,即不加载任何资源- 样式表: 只信任 cdn.example.org 和 third-party.org
- 页面子内容,如 、: 必须使用HTTPS协议加载
- 其他资源: 没有限制
CSRF 跨站请求伪造
是什么
CSRF(Cross-site request forgery)跨站请求伪造,利用用户的登录凭证,冒充用户,发送恶意请求。
受害者的步骤
1.登录受信任网站 A ,并在本地生成保存Cookie;
2.在不登出 A 情况下,访问病毒网站 B,
对于网站B来说只是利用cookie并没有获取到cookie。
XSS 是攻击者直接对我们的网站 A 进行注入攻击,CSRF 是通过网站 B 对我们的网站 A 进行伪造请求。
举例
例如:登录购物网站 A 之后点击一个恶意链接 B,B 请求了网站 A 的下单接口,结果是在网站 A 的帐号生成一个订单。
原理是:网站 B 通过表单、get 请求来伪造网站 A 的请求,这时候请求会带上网站 A 的 cookies,浏览器允许跨域提交表单,若登录态是保存在 cookies 中,则实现了伪造攻击。
CSRF防御
使用Cookie的SameSite属性
在 HTTP 响应头中,设置 Cookie 时,带上 SameSite 选项,限制第三方的cookie。
Token验证
可以手动设置一个状态字段,浏览器请求页面数据的时候带过去,请求关键数据的时候通过请求字段携带状态字段。因为CSRF不能访问用户页面数据,就可以保证请求是合法的。
比如:
可以在 HTTP 请求中以参数的形式加入一个随机产生的 Token,并在服务器端建立一个拦截器来验证这个 Token,如果请求中没有 Token 或者 Token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。
总结
出现XSS和CSRF漏洞的原因就是因为浏览器的同源策略开了两个口子
- 在页面中可以任意引用第三方资源
- 通过 CORS 策略让 XMLHttpRequest 和 Fetch 去跨域请求资源。
引入了 HttpOnly 机制来禁止第三方资源发送一些关键 Cookie
引入了 SameSite 来防止CSRF跨域请求的攻击。