这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战
这篇笔记将从攻击和防御两个方面记录web开发安全知识相关知识。
攻击篇
XSS
XSS跨站脚本攻击,全称是 Cross Site Scripting,为了与CSS
区分开来,故简称 XSS。XSS 攻击是指黑客往 HTML 文件中或者 DOM 中注入恶意脚本,从而在用户浏览页面时利用注入的恶意脚本对用户实施攻击的一种手段。
XSS的一些特点:
- 通常难以从UI上感知(暗地里执行脚本)
- 窃取用户信息(cookie/token)
- 绘制UI(例如弹窗),诱骗用户点击/填写表单
一个简单的例子:我们期望用户在content
中输入正常的内容,结果黑客提交了恶意脚本,就形成了XSS攻击。
<div>${content}</div>
content:`<script>alert("XSS")</script>`
复制代码
原本的代码变为:
<div>
<script>alert("XSS")</script>
</div>
复制代码
XSS可以分为存储型XSS、反射型XSS、基于 DOM 的 XSS 攻击、mutation-based XSS
存储型 XSS
这种攻击方式是将恶意脚本存在数据库中
当用户访问了这个页面,服务器就会从客户端读数据。恶意脚本可以通过XMLHttpRequest 或者 Fetch 将用户的 Cookie 数据上传到黑客的服务器。
这种XSS危害大,全局可见。
反射型XSS
这种方式不涉及数据库,从url上攻击。比如在发送到服务器的请求url里加上恶意代码,服务器又将这段恶意代码返回给客户端。因此,不明来源的链接不要乱点。
基于DOM的XSS
这种方式不需要服务器参与,恶意攻击的发起和执行全在浏览器内完成,一般是通过劫持html文件进行篡改。
mutation-based XSS
利用了浏览器渲染DOM的特性(独特优化),按浏览器进行攻击
CSRF
CSRF(Cross-site request forgery),跨站请求伪造。就是指当和我们打开不明网站时,黑客利用用户的登录状态发起的跨站请求。在用户不知情的前提下,利用用户权限,也就是cookie等信息构造指定的HTTP请求,窃取或修改用户敏感信息。
injection注入攻击
SQL注入
SQL注入是比较常见的网络攻击方式之一,后台接收到用户输入的数据,并且在sql语句中使用这个数据,如果过滤不严,就会让恶意代码注入到你的sql语言中。
比如在常用的密码校验里,类似这样的sql语句
Select id From users Where user_id='' And password=''
复制代码
当密码为1'or'1'='1
,sql语句就变成了
Select id From users Where user_id='' And password='1'or'1'='1'
复制代码
SQL语句的查询结果为永远是true
,就可以实现无账号登录之类的功能。更有甚者,直接删除数据库。
除此之外,还有一些其他的注入方式,比如CLI、OS command、SSRF(Server-Side Request Forgery:服务器端请求伪造)。严格来说这个SSRF不是注入攻击,但是原理类似,一般用于攻击内网系统。
DoS
DoS(Denial of Service)其目的是使计算机或网络无法提供正常的服务。通过某种方式,导致服务器资源被显著消耗,来不及响应更多请求,导致请求挤压,进而雪崩效应。
ReDoS:基于正则表达式的DoS
正则表达式使用贪婪模式,不适用?
,有多少匹配多少的时候,攻击者可以构造特殊的字符串来大量消耗服务器的系统资源,造成服务器的服务中断或停止。
Distributed DoS(DDoS)
洪水攻击,短时间内,来自大量僵尸设备的请求流量,服务器不能及时完成全部请求,导致请求堆积,进而雪崩效应,无法响应新请求。特点是直接访问IP,使用任意API,消耗大量带宽。
中间人攻击
比如使用http进行明文传输的时候,攻击者很容易进行劫持,篡改数据,这时候客户端和服务端都无法验证对方身份,但是认为这个中间人就是另一方。因此后来引入了HTTPS协议。
防御篇
防御XSS
首先原则是永远不要相信用户的提交内容,不要将用户的提交内容直接转化成DOM。
如今有一些现场的工具帮助我们防御XSS攻击,前端主流框架默认防御XSS,谷歌也提供了一个防御的JS库google-closure-library。
服务端(Node)可以使用DOMPurify。DOMPurify 将删除所有包含危险 HTML 的内容,从而防止 XSS 攻击和其他恶意行为。
有几种情况是需要尽量避免的:
- 必须要动态生成DOM,string生成dom的情况
- 允许用户上传SVG,因为svg可以内嵌script标签
- 允许用户自定义跳转链接,也是可以内嵌代码
- 允许用户自定义样式
如果必须要用,需要做好过滤。
同源策略
同源是指两个 URL 的协议、域名和端口都相同。
DOM 层面,同源策略限制了来自不同源的 JavaScript 脚本对当前 DOM 对象读和写的操作。
数据层面,同源策略限制了不同源的站点读取当前站点的 Cookie、IndexDB、LocalStorage 等数据。
网络层面,同源策略限制了通过 XMLHttpRequest
等方式将站点的数据发送给不同源的站点。
CSP
为了解决跨站攻击,最简单的方法就是全部禁止跨站资源请求,可是这样会让web应用难以开发,因此浏览器做了部分让步,让页面中可以嵌入第三方资源。当然这会带来安全性问题,由此引入了CSP
。
CSP
(Content-Security-Policy)内容安全策略是一个额外的安全层,用于检测并削弱某些特定类型的攻击,包括跨站脚本和数据注入攻击等。
CSP
的核心思想是让服务器决定浏览器能够加载哪些资源,让服务器决定浏览器是否能够执行内联 JavaScript 代码。
可以在服务器的响应头部添加CSP,self标签引入:
浏览器meta标签中引入:
防御CSRF
由于CSRF攻击,需要网站存在CSRF漏洞,同时用户要有网站的登录状态,黑客需要通过第三方站点发起攻击。那么对应的我们有三种防御方式:
- 限制请求来源,验证origin和referrer
- 使用token验证用户
- 充分利用好 Cookie 的 SameSite属性,禁止发送某些关键 Cookie 数据到服务器。
此时要设置用户绑定,因为用户自己也可以是攻击者。还有过期时间,防止黑客使用以前的数据。
防御iframe攻击
可以使用X-Frame-Options。
这种攻击方式是指用iframe嵌套一个透明不可见的页面,让用户在不知情的情况下,
点击攻击者想要欺骗用户点击的位置。
防御anti-pattern攻击,避免将post和get写在一起。
防御DoS
进行code review 少用贪婪模式的正则。进行代码扫描,对正则性能测试,拒绝使用用户提供的正则表达式。常用的方法有:
- 流量治理
- 负载均衡
- API网关
- CDN
- 快速自动扩容
- 非核心服务降级
防御中间人攻击
使用HTTPS,HTTPS比HTTP多了TLS安全验证,采用对称加密的方式加密传输数据和非对称加密的方式来传输密钥。同时,为了验证服务器,又引入了CA证书和数字签名的形式。
记录一下课堂上的推荐读物: