这是我参与「第四届青训营 」笔记创作活动的的第6天
两个角度看 Web 安全
从攻击者的角度
Cross-Site Scripting (XSS ,跨站脚本攻击)
因为跨站脚本攻击的缩写会与层叠样式表的缩写(CSS)混淆,所以将跨站脚本攻击缩写改为 XSS。
在开发维护的页面中,攻击者通过这种方式把他的恶意脚本注入了进来。
主要利用了:
- 开发者盲目信任用户提交的内容
- 作为前端工程师,我们直接把用户提交的字符串转化成了 DOM
一些特点:
- 通常难以从 UI 上感知(暗地执行脚本)
- 窃取用户信息(cookie/token)
- 绘制 UI (例如弹窗),诱骗用户点击/填写表单
按性质分类:
1. 存储型
• 恶意脚本被存在数据库中
• 访问页面 -> 读数据 = 被攻击
• 危害最大,对全部用户可见
像下图这样(攻击者提交的内容为 <script>alert("xss")</script>),攻击者就完成了一次存储型的 XSS 攻击。
2. 反射型
• 不涉及数据库
• 从 URL 上攻击
3. 基于 DOM
• 不需要服务器的参与
• 恶意攻击的发起 + 执行,全在浏览器完成
4. 基于 Mutation
• 利用了浏览器渲染 DOM 的特性(独特化)
• 不同浏览器,会有区别(按浏览器进行攻击)
在很多的 XSS 过滤工具之中都会把此处的 title 属性当作一个很正常的字符串属性,合法、合理、没问题,但实际上把这段 HTML 片段拿到浏览器中进行渲染的话,就有可能得到下图结果:
因为 img 的 src 属性不符合规范,就会触发 onerror 事件, onerror 事件回调函数一触发就完成了 XSS 攻击。
基于 Mutation 的 XSS 攻击非常巧妙,攻击者非常懂得浏览器是如何渲染 DOM 的,也是最难防御的一种 XSS 攻击方式。
反射型和基于 DOM 的区别:
完成注入脚本的地方。反射型的恶意脚本是在服务器中进行注入,基于 DOM 的 XSS 攻击在浏览器中完成整个闭环。
Cross-Site Request Forgery (CSRF ,跨站伪造请求)
在用户不知情的前提下利用用户权限(cookie)构造指定 HTTP 请求,窃取或修改用户敏感信息。
用户收到一封 Email ,Email 中有一个链接,用户点击链接访问了一个恶意的页面,在恶意的页面中攻击者构造了一个 HTTP 请求(例如:向银行发起一个转账请求),而这个请求(转账请求)在另外一个域名,假设右边的 Server A 也就是银行的服务器接收到了这个请求,发现请求上有用户的 cookie ,然后 cookie 还验证通过了,它就认为这是一个合法的用户请求,然后就执行转账接口,完成转账返回结果。
整个过程中用户没有访问银行的任何页面,但是银行页面中对应的特定接口却被请求了而且请求还被成功执行了。
跨站伪造请求最常见的就是 GET 请求方式而且非常容易被构建。
GET 请求方式,例:
• href 为恶意网址的 a 标签,用户只要一点击就可以完成一次攻击。
• src 为恶意网址的 img 标签,用户只要一访问这个页面,图片一被加载就会完成一次 GET 请求也就是完成一次 CSRF 的攻击。
POST 请求方式,例:
• method 为 POST 的表单。
Injection (注入)
- SQL Injection (最常见)
有一个 HTTP 请求, SQL 参数在请求上带入,然后这个请求达到了服务器端;服务器在 HTTP 请求上读参数,构造出一个 SQL 语句,然后去运行这段 SQL 代码;这段代码被执行之后可能导致攻击者能够获取其他数据、删除数据、修改数据等。
例如:
服务器端代码:
请求:
服务器端构造出的 SQL 语句:
服务器端一旦执行这种代码,删库跑路。
- CLI (命令行)
- OS command (系统命令)
第 2 点和第 3 点非常类似,用同一个例子(视频转换):
调 convert-cli 去对视频的格式进行转换,这里接收用户传递的 options 参数并且不进行任何的过滤。
攻击者把 options 字段传入系统命令时(比如: rm 语句),当服务端去执行这个命令时就会把服务器端的若干个文件进行删除,服务器就可能直接 down 机。
例2(读取修改):
以 nginx 的配置为例,假如攻击者能够修改我们的 nginx 配置,那么他可以把我们网站上的请求,全部代理转发到另外一个网站。
- Server-Side Request Forgery (SSRF ,服务器端伪造请求)
严格而言, SSRF 不是 Injection ,但是原理类似。
SSRF 攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)。
通俗来讲,有两个网站:
A 网站,所有人都可以访问的外网网站的;
B 网站,只能内部访问的网站;
A 网站能访问 B 网站。
所以,作为普通用户,我们可以访问 A 网站,然后篡改获取资源的来源,请求从 B 网站获取资源。 A 网站没有检测我的请求合不合法,以自己 A 网站的身份去访问 B 网站,于是我们就有机会攻击 B 网站。
DoS (Denial of Service)
通过某种方式构造特定请求,导致服务器资源被显著消耗来不及响应更多请求,导致请求挤压,进而雪崩效应。
- ReDoS :基于正则表达式的 DoS
“⚡”表示正则表达式可以非常快的完成匹配,“🤔”表示思考了一下,“❌”表示正则表达式没匹配成功,箭头右框写的是 "abababababababa" 推导的伪代码。(“*” 我没看明白)
右框的所有字符串的末尾都省略了一个字符“a”所以整体字符串不为若干“ab”重复,正则表达式没匹配成功,尝试给整个字符串减少一个“ab”进行正则匹配试试,又没匹配上,接着减少,……,直到最后发现它就是匹配不上,最终放弃。不断减少一次重复“ab”就是一个典型的回溯行为。
服务器端写了一个贪婪的正则表达式而攻击者可以传入一个容易发生回溯行为的字符串,这样导致的效果就是服务器端响应时间会大大的延长,接口吞吐量明显降低,响应用户的请求次数大大下降。
- Logical DoS
DDoS (Distributed DoS)
短时间内,来自大量僵尸设备的请求流量,服务器不能及时完成全部请求,导致请求堆积,进而雪崩效应,无法响应新请求。「不搞复杂的,量大就完事」
攻击特点:
- 直接访问 IP
- 任意 API
- 消耗大量带宽(耗尽)
洪水攻击:TCP 三次握手协议,攻击者构造大量的 TCP 请求,发大量的 SYN 给我们的服务器,服务器按照规范返回 ACK + SYN ,但攻击者此时不会返回第三次 ACK ,导致三次握手没有完成,连接不能释放,服务器达到最大的连接次数之后就不会再响应新的请求。
传输层
中间人攻击方式(最主要、最常见):
这种方式是中间人在浏览器和服务器中插了一杠子,浏览器以为自己在和浏览器进行交互而服务器以为自己在给浏览器返回数据,实际上它们都在和一个中间人进行沟通。
中间人可以做什么?
- 窃取信息
- 修改请求
- 修改返回结果
- ……
什么角色可以扮演中间人?
- 恶意的浏览器(webview)
- 路由器
- ISP
- ……
中间人可能发生主要有三点:
- 传输的信息大家都看得懂(明文传输);
- 传输的信息被篡改时,浏览器和服务器都不知道(信息篡改不可知);
- 服务器和浏览器都没有对对方的身份进行验证(对方身份未验证)。
代理和中间人攻击方式的区别(自我认识):
- 浏览器一定知道代理,服务器不一定知道代理;
- 代理得到浏览器方的认可。