XSS跨域脚本攻击 和 CSRF跨站请求伪造攻击
-
总结
1、页面安全问题 的主要原因:浏览器为 同源策略 开的两个后门
- ①页面可引用 第三方资源
- ②『通过 CORS 策略』实现 跨域 请求资源
2、为了解决这些问题:
- 引入了『 CSP内容安全策略 』来限制页面任意引入外部资源
- 引入了『
HttpOnly
机制』来禁止XMLHttpRequest
或者Fetch
发送一些关键Cookie
- 引入了『
SameSite
』和Origin
来防止 CSRF 攻击
XSS跨域脚本攻击
XSS攻击 Cross Site Script :即 跨域脚本攻击(为和CSS区分,改叫XSS)
-
总结
1、XSS 攻击就是黑客往页面中注入恶意脚本,使之在客户端运行,然后将页面的一些重要数据上传到恶意服务器
2、常见的三种 XSS 攻击模式是 存储型 XSS 攻击、反射型 XSS 攻击和 基于 DOM 的 XSS 攻击
-
共同点
都是需要 往用户的页面中注入恶意脚本,然后再 通过恶意脚本将用户数据上传到黑客的恶意服务器上
-
不同点
在于 注入的方式不一样,有通过服务器漏洞来进行注入的,还有在客户端直接注入的
3、针对这些 XSS 攻击,主要有三种 防范策略
【核心】阻止恶意 JavaScript 脚本的注入和恶意消息的发送来实现
- 1、通过 服务器 对输入的内容进行 过滤或者转码
- 2、充分利用好 CSP内容安全策略
- 3、使用
HttpOnly
来保护重要的 Cookie 信息
-
1、反射型 — 恶意链接
-
【简单描述】
将用户输入的存在 XSS 攻击的数据,发送给后台,后台并未对数据进行存储,也未经过任何过滤,直接返回给客户端,被浏览器渲染
-
【具体步骤】
1、构造出包含恶意代码的 url,url 指向目标网站,参数拼接恶意代码,举例如下:
2、诱导用户点击,点击后会向服务端发送请求,同时查询参数携带恶意代码
3、服务端返回时 将恶意代码直接拼接在HTML
4、客户端接收并解析执行代码时,恶意代码也被执行
-
【特点】
需要攻击者诱使用户操作:点击一个恶意链接/提交一个表单/进入一个恶意网站
-
【常见场景】
通过 URL 传递参数的场景,如 网站搜索、跳转
2、存储型
-
【简单描述】
数据库中存有存在XSS攻击的数据,返回给客户端,数据未经任何转义被浏览器渲染
-
【具体步骤】
1、把恶意代码提交到服务器端
2、当浏览器向服务器请求数据时,恶意代码拼接在HTML中 从服务器传回
3、客户端解析时被执行恶意代码,将用户 Cookie 信息等数据上传到恶意服务器
-
【特点】
这种 XSS 攻击具有 很强的稳定性
-
【常见场景】
论坛发帖、商品评论、用户私信 等,攻击者发布包含恶意 JS 代码的评论,所有访问的用户的浏览器中会被执行这段恶意的 JS 代码
3、基于 DOM 的 XSS 攻击
-
【特点】
通过恶意脚本修改页面的 DOM 结构,是纯粹发生在客户端的攻击。
-
【可能性】
1、
<script>
标签2、a 标签的
href
、img
上src
,例如:<img src="javascript:alert('XSS')” />
3、
innerHTML/outerHTML=xx
或setTimeout/setInterval
(执行js)4、
document.write
或eval
5、
location
、onclick
、onerror
、onload
、onmouseover
等事件(执行js),例如:<img src="#" onerror=“alert('1')" />
6、在 style 属性中,包含类似
background-image:url(“javascript:alert('XSS')”);
的代码(新版本浏览器已经可以防范)7、在 style 属性和标签中,包含类似
expression(…)
的 CSS 表达式代码(新版本浏览器已经可以防范)
XSS 攻击解决方案
无论是何种类型的 XSS 攻击,它们都有一个 共同点,那就是首先 往浏览器中注入恶意脚本,然后再通过恶意脚本将用户信息发送至黑客部署的恶意服务器上
我们可以通过阻止【恶意 JavaScript 脚本的注入】和【恶意消息的发送】来实现
XSS 攻击解决方案 | 详细说明 | 解决问题 |
---|---|---|
防范反射型、存储型 XSS | 1、采用纯前端渲染 2、拼接 HTML 时,要对 HTML 进行充分转义(过滤 <script> 标签,或者转码 <script> —> <script> ) |
即使这段脚本返回给页面,页面也不会执行这段脚本 |
防范 DOM 型 XSS | 1、将用户输入插入 HTML 或拼接 js 执行时,要进行编码,将一些特殊字符转义 2、对于 a 标签的 href 等外链请求,添加 白名单 进行过滤,禁止以 javascript: 开头的链接,和其他非法的 scheme |
|
内容安全策略 CSP | 内置于浏览器,只信任 白名单网站 详解见下方 | 核心思想是让服务器决定浏览器能够加载哪些资源,让服务器决定浏览器是否能够执行内联 JavaScript 代码,大大减少XSS攻击 |
HttpOnly 标准 (防止劫取 Cookie) (HttpOnly是服务器通过响应头来设置的) |
浏览器禁止页面的 JS 访问带有 HttpOnly 属性的 Cookie |
攻击者通过注入恶意脚本获取用户的 Cookie 信息,发起 Cookie劫持攻击;HttpOnly 【阻止 XSS 攻击后的 Cookie 劫持攻击】; |
用户的输入检查 (XSS Filter) | 不要相信用户的任何输入,要进行检查、过滤和转义 | 检查用户输入中是否包含 <,> 等特殊字符,如果存在,则对特殊字符进行 过滤或编码 |
服务端输出检查 | 除富文本的输出外,在变量输出到 HTML 页面时,可以使用 编码或转义 的方式来防御 XSS 攻击 |
【特别关注】内容安全策略 CSP
现在主流的浏览器内置了 CSP,它的实现/执行全部 由浏览器完成,开发者只需配置。
【CSP 实质】
白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。
【CSP 作用】
- 限制加载其他域下的资源文件,这样即使黑客插入了一个 JavaScript 文件,这个 JavaScript 文件也是无法被加载的
- 禁止向第三方域提交数据,这样用户数据也不会外泄
- 禁止执行 内联脚本 和 未授权的脚本
- 还提供了 上报机制,这样可以帮助我们尽快发现有哪些 XSS 攻击,以便尽快修复问题
【CSP 报错】
启用后,不符合 CSP 的外部资源就会被阻止加载,报错截图如下:
实际案例:
访问 www.shemore.cn
时,由于请求了 m.beidianyx.com
下的文件,出现了报错
1、需要把当前域名配置入 Content-Security-Policy
中 比如水梦露官网的新域名:www.shemore.cn
m.beidianyx.com
。
2、如果 route 的配置的地址和当前页面路径不一致时,需要手动在 controller
中配置静态资源路径 ctx.state.path
【启用 CSP的两种方法】
1、HTTP 响应头 Content-Security-Policy
2、网页的 <meta>
标签
属性值 | 描述 |
---|---|
default-src ‘self’ | 用来设置下面图中各个选项的默认值 限制所有的外部资源,都只能从当前域名加载 |
script-src ‘self’ | 脚本:只信任当前域名 |
child-src https: | 框架(frame):必须使用 HTTPS 协议加载 |
report-uri | 告诉浏览器,应该把注入行为报告给哪个网址 |
跨站请求伪造 CSRF
Cross Site Request Forgery,攻击者借助受害者的 Cookie 骗取服务器的信任以操作服务端数据。
–> 改变在服务端的数据,而非窃取数据
-
总结
1、要发起 CSRF 攻击需要具备三个条件
- 目标站点存在【漏洞】
- 用户要【登录】过目标站点
- 黑客需要通过【第三方站点】发起攻击
2、如何防止 CSRF 攻击,主要有三种方式:
-
充分利用好 Cookie 的
SameSite
属性 -
验证请求的 来源站点
-
使用 CSRF Token
-
【特点】
1、不能拿到 Cookie,也看不到 Cookie 的内容,仅仅是 冒用
2、向服务器提交操作,但是不直接窃取数据,对于 服务器返回的结果,由于浏览器同源策略的限制,攻击者也无法进行解析
3、攻击一般发起在 第三方网站,而不是被攻击的网站;被攻击的网站无法防止攻击发生
-
【步骤】
1、用户登录受信任网站A,并在本地生成 Cookie
2、在 不登出A的情况下,访问危险网站B
-
【实现方式】
1、打开黑客的站点后 自动发起 Get/POST 请求
2、引诱用户点击黑客站点上的链接
-
【案例】
跨站请求可以用各种方式:图片URL、超链接、CORS(跨域资源共享)、Form提交等等;
受害者登录 a.com,并保留了登录凭证(Cookie)–> 攻击者引诱受害者访问了 b.com –> b.com 向 a.com 发送了一个请求:a.com/act=xx。浏览器会默认携带 a.com 的 Cookie –> a.com 接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求 –> a.com 以受害者的名义执行了 act=xx –>攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让 a.com 执行了自己定义的操作。
跨站请求伪造 CSRF 防范措施
方式 | 解析 |
---|---|
验证码 【体验差】 |
【优点:最简洁而有效的防御方法 —辅助手段,不能给所有操作加验证码】 强制用户必须与应用进行交互,才能完成最终请求 |
同源验证 Referer Check ,HTTP 请求头中的一个字段 |
【Referer 记录了该 HTTP 请求的来源地址】服务端通过 Referer 可以检查请求 是否来自合法的源:`if (req.headers.referer !== ‘http://www.c.com/’) { res.write(‘csrf 攻击’); return;} |
Cookie 的 SameSite 属性 (在 HTTP 响应头中,通过 set-cookie 字段设置 Cookie 时,可以带上 SameSite 选项) |
禁止Cookie的发送 如果是从第三方站点发起的请求,那么需要浏览器禁止发送某些关键 Cookie 数据到服务器 |
添加 token 验证 【工作量大】 | 【关键在于 在请求中放入攻击者所不能伪造的信息,并且不存储于 Cookie 之中】服务器生成一个 Token,并把这个 Token 利用算法加密,加密后的字符串植入到页面 session中。在页面加载时,在每个 a 标签和form标签中放入 Token 服务器验证 Token是否正确 |
双重Cookie验证 | 【优点:无需使用Session,易于实施,可以在前后端统一拦截校验】 【缺点:Cookie 中增加了额外的字段,如果有 XSS 攻击,该防御失效,使用该方案时确保整站HTTPS的方式】 利用 CSRF 攻击不能获取到用户 Cookie 的特点,我们可以要求请求携带一个Cookie中的值。在用户访问网站页面时,向请求域名注入一个 Cookie,内容为随机字符串。在前端向后端发起请求时,取出 Cookie,并添加到 URL 的参数中。后端接口验证Cookie中的字段与URL参数中的字段是否一致,不一致则拒绝。 |