Web 开发的安全之旅
我们分别从攻击和防御2个角度看 web 安全
Hacker-攻击者
Cross-Site Scripting (XSS)
什么是 XSS
Cross-Site Scripting(跨站脚本攻击)简称 XSS,是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。
XSS 的本质是:恶意代码未经过滤,与网站正常的代码混在一起;浏览器无法分辨哪些脚本是可信的,导致恶意脚本被执行。

特点
- 通常难以从 UI 上感知 (暗地里执行脚本)
- 窃取用户信息(cookie/token)
- 绘制 UI (例如弹窗),诱骗用户点击/填写表单
XSS Demo
👿 可以直接提交恶意脚本
Stored XSS (存储型 XSS)
Stored XSS
- 恶意脚本被存在数据库中
- 访问页面 -> 读取数据 == 被攻击
- 危害最大,对全部用户可见

Reflected XSS (反射型XSS)
Reflected
- 不涉及数据库
- 从 URL 上攻击
DOM-based XSS (基于DOM型)
DOM-based XSS
- 不需要服务器的参与
- 恶意攻击的发起 + 执行,全在浏览器完成
浏览器
Reflected VS DOM-based
⚠️完成注入脚本的地方不同⚠️
Reflected
- 基于Server 完成注入
DOM-based
- 基于浏览器完成整个闭环

Mutation-based XSS
Mutation-based XSS
- 利用浏览器渲染 DOM 的特性(独特优化)
- 不同浏览器,会有区别(按浏览器进行攻击)
在 Chrome 浏览器中会被渲染成以下这段代码
src
属性不符合规范,触发onerror
事件,完成攻击
Cross-site request forgery(CSRF 跨站伪造请求)
什么是 CSRF
CSRF,是跨站请求伪造(Cross Site Request Forgery)的缩写,是一种劫持受信任用户向服务器发送非预期请求的攻击方式。
通常情况下,CSRF 攻击是攻击者借助受害者的 Cookie 骗取服务器的信任,在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击服务器,从而在并未授权的情况下执行在权限保护之下的操作。
特点
- 在用户不知情的前提下
- 利用用户权限(cookie)
- 构造指定 HTTP 请求,窃取或修改用户敏感信息
CSRF Demo
CSRF- GET/beyond GET
Injection(注入)
SQL 注入
SQL 注入(SQLi)是一种可执行恶意 SQL 语句的注入攻击。这些 SQL 语句可控制网站背后的数据库服务。攻击者可利用 SQL 漏洞绕过网站已有的安全措施。他们可绕过网站的身份认证和授权并访问整个 SQL 数据库的数据。他们也可利用 SQL 注入对数据进行增加、修改和删除操作。
SQL 注入可影响任何使用了 SQL 数据库的网站或应用程序,例如常用的数据库有 MySQL、Oracle、SQL Server 等等。攻击者利用它,便能无需授权地访问你的敏感数据,比如:用户资料、个人数据、商业机密、知识产权等等。SQL 注入是一种最古老、最流行、也最危险的网站漏洞。OWASP 组织(Open Web Application Security Project)在 2017 年的 OWASP Top 10 文档中将注入漏洞列为对网站安全最具威胁的漏洞。
Deom 1
- 读取请求字段
- 直接以字符串的形式拼接 SQL 语句
Injection 不止于 SQL
- CLI
- OS command
- Server-Side Request Forgery(SSRF),服务端伪造请求
- 严格来说,SSRF 不是 injection,但原理类似
Demo 2
执行
读取+修改
- 修改配置文件
- 流量转发到真实第三方
- 第三方扛不住新增流量
- 第三方服务挂掉
SSRF Demo
- 请求 [用户自定义] 的 callback URL
- callback URL 可能是一些内网才能访问的路径
- web server 通常有内网权限

Denial of Service(DoS 拒绝服务)
什么是 DoS
DoS(Denial Of Service),拒绝服务的缩写,是指故意攻击网络协议实现的缺陷或直接通过野蛮手段耗尽被攻击对象的资源,目的是让目标计算机或网络无法提供正常的服务,使目标系统停止响应甚至崩溃。这些服务资源包括网络带宽,文件系统空间容量,开放的进程或者允许的连接。这种攻击会导致资源的匮乏,无论计算机的处理速度多快、内存容量多大、网络带宽的速度多快都无法避免这种攻击带来的后果。
大多数的DoS攻击是需要相当大的带宽的,而以个人为单位的黑客没有可用的高带宽资源。为了克服这个缺点,DoS攻击者开发了分布式的攻击。攻击者利用工具集合许多的网络带宽来同时对同一个目标发动大量的攻击请求,这就是DDoS(Distributed Denial Of Service)攻击。可以说DDoS攻击是由黑客集中控制发动的一组DoS攻击的集合,这种方式被认为是最有效的攻击形式,并且非常难以抵挡。
通过某种方式(构造特定请求),导致服务器资源被显著消耗,来不及响应更多请求,导致请求挤压,进而雪崩效应。
http://bucarotechelp.com/networking/security/81070501.asp
ReDos:基于正则表达式的 DoS
正则表达式-贪婪模式
重复匹配时「?」VS「no?」:满足 “一个” 即可 VS 尽量多
- 贪梦:n 次不行?n-1次再试试?-回溯
- 接口时间 上升
- 接口吞吐量 下降
Logic DoS
逻辑攻击的目标与洪水攻击相同,但入侵的方法却大不相同,而且往往更微妙。虽然洪水攻击通常看起来用异常高的标准流量轰炸服务器,但逻辑攻击依赖于非标准流量,通过系统中的安全漏洞进行利用。
- 耗时的同步操作
- 数据库写入
- SQL join
- 文件备份
- 循环执行逻辑

Distributed DoS (DDoS)
短时间内,来自大量僵尸设备的请求流量,服务器不能及时完成全部请求,导致请求堆积,进而雪崩效应,无法响应新请求。
攻击特点
- 直接访问 IP
- 任意 API
- 消耗大量带宽(耗尽)
TCP 三次握手
- 攻击者发送 SYN 给服务器
- 服务器正常返回 ACK+SYN
- 攻击者不返回第三次 ACK
- 导致连接没有完成,大量的连接不能被释放
中间人攻击
什么是中间人攻击
在 http 数据提交给 TCP 层之后,会经过用户电脑、路由器、运营商、服务器,这中间每一个环节,都不是安全的
一句话就是:在 http 传输过程中容易被中间人窃取、伪造、篡改,这种攻击方式称为中间人攻击。
- 明文传输
- 信息篡改不可知
- 对方身份未验证

开发者-防御者
XSS
- 永远不要相信用户提交的内容
- 不要将用户提交的内容直接转换成 DOM

现成工具

用户需求,必须动态生成 DOM
**string**
**-> ****DOM**
- ⚠️必须对
**string**
进行转义⚠️
- ⚠️必须对
- 上传 SVG
- 需要对 SVG内容进行扫描
- **因为 **
**SVG**
**标签允许插入 ****script**
标签 - 如果图片加载
**script**
执行,完成攻击 -
**Blob**
** 动态生成 ****script**
- **尽量不要将 blob 类型设为 **
**text/javascript**
-
- **尽量不要将 blob 类型设为 **
- 自定义跳转链接
- 尽量不要允许用户自定义链接,如果有这个需求也一定要做好过滤
-
- 自定义样式
-
Same-orgin Policy(同源策略)

- **HTTP 同源是没有问题的,跨域需要查看服务器设置 **
Content Security Policy(CSP 内容安全策略)
- 哪些源(域名)被认为是安全的
- 来自安全源的脚本可以执行,否则直接抛措
- 对 eval+inline script 拒绝

CSRF
可以通过请求头部校验
可以通过 token 校验
- 用户绑定:攻击者也可以是注册用户===可以获取自己的 tokn
- 过期时间:【前向保密】
iframe 防御
- 可以通过设置
X-Frame-Options
响应头

anti-pattern
GET!==GET+POST
避免用户信息被携带:SameStie Cookie
SameStie Cookie
SameSite 属性可以让 Cookie 在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击
限制的是:
- Cookie domain
- 页面域名
- 依赖Cookie的第三方服务怎么办?
- 内嵌一个X站播放器,识别不了用户登录态,发不了弹幕
- **可以设置
**SameSite**
为 ****none**
-
SameSite VS CORS

SameSite Demo


防御 CSRF 的正确姿势
通过中间件专门生成防御CSRF的策略
Injection
SQL 注入
- 找到项目中查询 SQL 的地方
- 使用 prepared statement
- 预编译
- 注入只对SQL语句的编译过程有破坏作用,而执行阶段只是把输入串作为数据处理,不再需要对SQL语句进行解析

SQL 注入 以外的注入
- CLI
- OS command
- SSRF

DoS

- 做好 Code Review ,避免出现
**/(ab*)+/**
这样的贪婪模式 - 避免把用户自定义的正则暴露在外
- 尽量拒绝用户自定义正则
Logical DoS

DDoS

传输层-中间人
HTTPS

- 可靠性:加密 避免了明文传输
- 完整性:MAC验证 避免了篡改
- 不可抵赖性:数字签名 确保了双方身份可被信任
成也证书败也证书
- 当签名算法不够健壮时,签名算法是有可能被破解的

Subresource Integrity (SRI)
- SRI 可以有效防御 CDN 资源劫持
- SRI 全称 Subresource Integrity 子资源完整性,是指浏览器通过验证资源的完整性(通常从 CDN 获取)来判断其是否被篡改的安全特性。
- 通过给 link 标签或者 script 标签增加 integrity 属性即可开启 SRI 功能
标签 hash (原始内容hash)VS 实际内容hash
Feature Policy/Permission Policy
什么是 Feature Policy
Feature Policy是一个新的http响应头属性,允许一个站点开启或者禁止一些浏览器属性和API,来更好的确保站点的安全性和隐私性。 可以严格的限制站点允许使用的属性是很愉快的,而可以对内嵌在站点中的iframe (allow 属性同样可以做到)进行限制则更加增加了站点的安全性。简而言之,这是一个允许 Web 开发人员有选择地启用和禁用各种浏览器功能和 API 的规范。这个规范有点类似 CSP,不同的是 CSP 控制安全,而 Feature Policy 则是控制功能。
跟其他http安全响应头的设置一样,只需要敲定页面具体的限制策略,然后在http响应头中返回相应的策略即可:
1 | Feature-Policy: vibrate 'self'; usermedia '*'; sync-xhr 'self' example.com |


总结
- 安全无小事
- 使用的依赖(npm package,甚至是NodeJS)可能成为最薄弱的一环
- npm install 除了带来了黑洞,还可以带来漏洞
- 请保持一颗热爱学习的心,攻击方式一直在前进,防御也不能停下脚步