文章目录
- [1.防 SQL 注入](#1.防 SQL 注入)
- [2.防 XSS](#2.防 XSS)
-
- [2.1 简介](#2.1 简介)
- [2.2 分类](#2.2 分类)
- [2.3 防御措施](#2.3 防御措施)
-
- [预防存储型和反射型 XSS 攻击](#预防存储型和反射型 XSS 攻击)
- [预防 DOM 型 XSS 攻击](#预防 DOM 型 XSS 攻击)
- 其他手段
- [2.4 小结](#2.4 小结)
- [3.防 CSRF](#3.防 CSRF)
-
- [3.1 简介](#3.1 简介)
- [3.2 示例](#3.2 示例)
- [3.3 防御措施](#3.3 防御措施)
- [3.4 小结](#3.4 小结)
- 4.防刷
- 5.防篡改
- 6.防重放
- [7.防 DDoS](#7.防 DDoS)
- 8.小结
- 参考文献
道路千万条,安全第一条。
虽然很多时候感觉网络攻击和安全事故离我们很远,但一旦发生,后面不堪设想,所以服务接口的安全问题是设计实现过程中不得不考虑的一环。
下面将列举常见的服务接口面临的安全问题与应对策略,来加固我们的服务,降低安全风险。
1.防 SQL 注入
什么是 SQL 注入?
SQL 注入攻击是通过将恶意的 SQL 语句插入到应用的输入参数中,再在后台 SQL 服务器上解析执行进行的攻击,它目前黑客对数据库进行攻击的最常用手段之一。
为什么要防 SQL 注入?
如果用户输入的数据被构造成恶意 SQL代码,程序又未对动态构造的 SQL 语句使用的参数进行审查,则会带来意想不到的危险。
- 篡改后台数据
- 盗取敏感信息
如何防 SQL 注入?
这是开发人员应该思考的问题,作为测试人员,了解如何预防 SQL 注入,可以在发现注入攻击 Bug 时,对 Bug 产生原因进行定位。
最有效防御方式:
- 预编译
将 SQL 代码提前编译成执行计划,用户提交的参数只会作为数据而不是 SQL 代码。
预编译使用参数化查询(Parameterized Query)的方式而非手动拼接 SQL。
预编译不仅可以防止 SQL 注入,还可以避免重复编译 SQL 带来性能提升。具体是怎样防止SQL注入的呢?实际上当将绑定的参数传到 MySQL 服务器,MySQL 服务器对参数进行编译,即填充到相应的占位符的过程中,做了转义操作。
辅助防御方式:
- 严格检查输入的类型和格式。
对于整数参数,加判断条件:不能为空、参数类型必须为数字。对于字符串参数,可以使用正则表达式进行过滤:如 [0-9a-zA-Z] 范围内的字符串。
- 过滤和转义特殊字符。
对用户输入的 SQL 参数进行转义,如' " / * %
等特殊字符。
- 禁用 root
将 SQL 账号的权限按需最小化,禁止使用 root 权限。
2.防 XSS
2.1 简介
XSS(Cross Site Scripting)名为跨站脚本攻击,因其缩写会与层叠样式表(Cascading Style Sheets,CSS)混淆,故将其缩写为 XSS。
XSS 漏洞是 Web 安全中最为常见的漏洞,通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页中,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是 JavaScript,但实际上也可以包括 Java、 VBScript、ActiveX、 Flash,甚至是普通的 HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和 Cookie 等各种内容。
XSS 本质是 HTML 注入。
2.2 分类
XSS 攻击通常可以分为 3 类:存储型(持久型)、反射型(非持久型)、DOM 型。
- 存储型 XSS
危害直接。跨站代码存储在服务器,如在个人信息或发表文章的地方加入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,每当有用户访问该页面的时候都会触发代码执行。
- 反射型 XSS
最为普遍。反射型跨站脚本漏洞,需要欺骗用户去点击链接才能触发 XSS 代码,一般容易出现在搜索页面。用户打开带有恶意代码的 URL 时,网站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器。用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
反射型和存储型 XSS 的区别是:存储型 XSS 的恶意代码存在数据库里,反射型 XSS 的恶意代码存在 URL 里。
- 基于 DOM 的 XSS
通过修改原始的客户端代码,受害者浏览器的 DOM 环境改变,导致恶意脚本执行。也就是说,页面本身并没有变化,但由于 DOM 环境被恶意修改,有客户端代码被包含进了页面,并且意外执行。DOM 型 XSS 攻击,实际上就是网站前端 JavaScript 代码本身不够严谨,把不可信的数据当作代码执行了。
DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞。
2.3 防御措施
通过前面的介绍可以得知,XSS 攻击有两大要素:
- 攻击者提交恶意代码。
- 浏览器执行恶意代码。
XSS 攻击主要是由程序漏洞造成的,要完全防止 XSS 安全漏洞主要依靠程序员较高的编程能力和安全意识,当然安全的软件开发流程及其他一些编程安全原则也可以大大减少 XSS 安全漏洞的发生。这些防范 XSS 漏洞原则包括:
预防存储型和反射型 XSS 攻击
存储型和反射型 XSS 都是在服务端取出恶意代码后,插入到响应 HTML 里的,攻击者刻意编写的"数据"被内嵌到"代码"中,被浏览器所执行。
预防这两种漏洞,常见做法:
- 输入校验。
不信任 UGC(用户提交的任何内容),对所有用户提交内容进行验证,包括对 URL、查询关键字、HTTP 头、REFER、POST 数据等,仅接受指定长度范围内、采用适当格式、采用所预期的字符的内容提交,对其他的一律过滤。
- 改成纯前端渲染,把代码和数据分隔开。
纯前端渲染的过程:
(1)浏览器先加载一个静态 HTML,此 HTML 中不包含任何跟业务相关的数据。
(2)然后浏览器执行 HTML 中的 JavaScript。
(3)JavaScript 通过 AJAX 加载业务数据,调用 DOM API 更新到页面上。
在纯前端渲染中,我们会明确的告诉浏览器:下面要设置的内容是文本(.innerText),还是属性(.setAttribute),还是样式(.style)等等。浏览器不会被轻易的被欺骗,执行预期外的代码了。
在很多内部、管理系统中,采用纯前端渲染是非常合适的。但对于性能要求高,或有 SEO 需求的页面,我们仍然要面对拼接 HTML 的问题。
- 拼接 HTML 时转义
如果拼接 HTML 是必要的,就需要采用合适的转义库,对 HTML 模板各处插入点进行充分的转义。常用的模板引擎,如 doT.js、ejs、FreeMarker 等,对于 HTML 转义通常只有一个规则,就是把& < > " ' /
这几个字符转义掉,确实能起到一定的 XSS 防护作用,但并不完善。
XSS 安全漏洞 | 简单转义是否有防护作用 |
---|---|
HTML 标签文字内容 | 有 |
HTML 属性值 | 有 |
CSS 内联样式 | 无 |
内联 JavaScript | 无 |
内联 JSON | 无 |
跳转链接 | 无 |
所以要完善 XSS 防护措施,我们要使用更完善更细致的转义策略。
预防 DOM 型 XSS 攻击
DOM 型 XSS 攻击,实际上就是网站前端 JavaScript 代码本身不够严谨,把不可信的数据当作代码执行了。
在使用 .innerHTML、.outerHTML、document.write() 时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用 .innerText、.textContent、.setAttribute() 等。
如果用 Vue/React 技术栈,并且不使用 v-html/dangerouslySetInnerHTML 功能,就在前端 render 阶段避免 innerHTML、outerHTML 的 XSS 隐患。
DOM 中的内联事件监听器,如 location、onclick、onerror、onload、onmouseover 等,<a>
标签的 href 属性,JavaScript 的 eval()、setTimeout()、setInterval() 等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,请务必避免。
html
<!-- 内联事件监听器中包含恶意代码 -->
<img onclick="UNTRUSTED" onerror="UNTRUSTED" src="data:image/png,">
<!-- 链接内包含恶意代码 -->
<a href="UNTRUSTED">1</a>
<script>
// setTimeout()/setInterval() 中调用恶意代码
setTimeout("UNTRUSTED")
setInterval("UNTRUSTED")
// location 调用恶意代码
location.href = 'UNTRUSTED'
// eval() 中调用恶意代码
eval("UNTRUSTED")
</script>
如果项目中有用到这些的话,一定要避免在字符串中拼接不可信数据。
其他手段
- Content Security Policy
严格的 CSP 在 XSS 的防范中可以起到以下的作用:
(1)禁止加载外域代码,防止复杂的攻击逻辑。
(2)禁止外域提交,网站被攻击后,用户的数据不会泄露到外域。
(3)禁止内联脚本执行(规则较严格,目前发现 GitHub 使用)。
(4)禁止未授权的脚本执行(新特性,Google Map 移动版在使用)。
(5)合理使用上报可以及时发现 XSS,利于尽快修复问题。
- Set-Cookie 设置 HttpOnly 属性
禁止 JavaScript 读取某些敏感 Cookie,攻击者即使完成 XSS 注入后也无法窃取此 Cookie。
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly
- 验证码
防止脚本冒充用户提交危险操作
- 主动检测和发现
(1)使用通用 XSS 攻击字符串手动检测 XSS 漏洞。
(2)使用扫描工具自动检测 XSS 漏洞。例如 Arachni、Mozilla HTTP Observatory、w3af 等。
2.4 小结
防范 XSS 是不只是服务端的任务,需要后端和前端共同参与的系统工程。虽然很难通过技术手段完全避免 XSS,但通过上面的做法可以有效减少漏洞的产生和 XSS 攻击带来的影响。
3.防 CSRF
3.1 简介
CSRF(Cross Site Request Forgery)名为跨站请求伪造,是一种挟制用户在当前已登录的 Web 应用程序上执行非本意操作的攻击方法。
攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。
一个典型的 CSRF 攻击有着如下的流程:
- 受害者登录 a.com,并保留了登录凭证(Cookie)。
- 攻击者引诱受害者访问了 b.com。
- b.com 向 a.com 发送了一个请求 a.com/act,浏览器默认会携带 a.com 的 Cookie。
- a.com 收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求。
- a.com 以受害者的名义执行了 act。
攻击者在受害者不知情的情况下,冒充受害者,让 a.com 执行了受害者定义的操作。
3.2 示例
假如一家银行转账操作的 URL 地址如下:
https://www.examplebank.com/withdraw?account=AccoutName&amount=1000&for=PayeeName
那么,一个恶意攻击者可以在另一个网站上放置如下代码:
<img src="https://www.examplebank.com/withdraw?account=Alice&amount=1000&for=Badman">
如果有账户名为 Alice 的用户访问了恶意站点,当图片被加载时,图片链接将被触发,而她之前刚访问过银行不久,登录信息尚未过期,那么她就会损失 1000 元。
这种恶意的网址可以有很多种形式,藏身于网页中的许多地方。此外,攻击者也不需要控制放置恶意网址的网站。例如他可以将这种地址藏在论坛,博客等任何用户生成内容的网站中。这意味着如果服务端没有合适的防御措施,用户即使访问熟悉的可信网站也有受攻击的风险。
透过例子能够看出,攻击者并不能通过 CSRF 攻击来直接获取用户的账户控制权,也不能直接窃取用户的任何信息。他们能做到的,是欺骗用户浏览器,让其以用户的名义运行操作。
3.3 防御措施
CSRF 通常从第三方网站发起,被攻击的网站无法防止攻击发生,只能通过增强自己网站针对 CSRF 的防护能力来提升安全性。
上文中讲了 CSRF 的两个特点:
- CSRF(通常)发生在第三方域名。
- CSRF 攻击者不能获取到 Cookie 等信息,只是使用。
针对这两点,我们可以专门制定防护策略,如下:
- 阻止不明外域的访问
(1)同源检测
(2)Samesite Cookie - 提交时要求附加本域才能获取的信息
(1)CSRF Token
(2)双重 Cookie 验证
以下我们对各种防护方法做详细说明。
(1)同源检测:验证 HTTP Referer 字段。
根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址。
以上文银行操作为例,Referer 字段地址通常应该是转账按钮所在的网页地址,应该也位于 www.examplebank.com 之下。而如果是 CSRF 攻击传来的请求,Referer 字段会包含恶意网址的地址,不会位于 www.examplebank.com 之下,这时候服务器就能识别出恶意的访问。
这种办法简单易行,工作量低,仅需要在关键访问处增加一步校验。但这种办法也有其局限性,因其完全依赖浏览器发送正确的 Referer 字段。虽然 HTTP 协议对此字段的内容有明确的规定,但其无法保证来访浏览器的具体实现,亦无法保证浏览器没有安全漏洞不会影响到此字段。并且也存在攻击者攻击某些浏览器,篡改 Referer 字段的可能。
(2)Samesite Cookie。
为了从源头解决这个问题,Google 起草了一份草案来改进 HTTP 协议,那就是为 Set-Cookie 响应头新增 Samesite 属性,它用来标明这个 Cookie 是个"同站 Cookie",同站 Cookie 只能作为第一方 Cookie,不能作为第三方 Cookie,Samesite 有三个属性值,分别是:
- Strict
- Lax(缺省值)
- None
Samesite=Strict
这种称为严格模式,表明这个 Cookie 在任何情况下都不可能作为第三方 Cookie。比如说 a.com 设置了如下 Cookie:
Set-Cookie: foo=1; Samesite=Strict
我们在 b.com 下发起对 a.com 的任意请求,foo 都不会被包含在 Cookie 中。
Samesite=Lax
Lax 规则稍稍放宽,大多数情况也是不发送 Cookie 给第三方,但是导航到目标网址的 Get 请求除外。
Set-Cookie: foo=1; SameSite=Lax;
导航到目标网址的 GET 请求,只包括三种情况:链接,预加载和 GET 表单。
请求类型 | 示例 | 正常情况 | Lax |
---|---|---|---|
链接 | <a href="..."></a> |
发送 Cookie | 发送 Cookie |
预加载 | <link rel="prerender" href="..."/> |
发送 Cookie | 发送 Cookie |
GET 表单 | <form method="GET" action="..."> |
发送 Cookie | 发送 Cookie |
POST 表单 | <form method="POST" action="..."> |
发送 Cookie | 不发送 |
iframe | <iframe src="..."></iframe> |
发送 Cookie | 不发送 |
AJAX | $.get("...") |
发送 Cookie | 不发送 |
Image | <img src="..."> |
发送 Cookie | 不发送 |
设置了 Strict 或 Lax 以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性。
Samesite=None
网站可以显式关闭 SameSite 属性,将其设为 None。不过,前提是必须同时设置 Secure 属性(Cookie 只能通过 HTTPS 协议发送),否则无效。
下面的设置无效。
Set-Cookie: foo=1; SameSite=None
下面的设置有效。
Set-Cookie: foo=1; SameSite=None; Secure
(3)CSRF Token。
CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中用户所有的验证信息都存在于 Cookie 中,因此黑客可以在不知道这些验证信息的情况下直接利用用户自己的 Cookie 通过安全验证。
要抵御 CSRF,关键在于在请求中放入黑客不能伪造的信息,并且该信息不存在于 Cookie 之中,并在服务器端建立一个拦截器验证这个 Token。如果请求中没有 Token 或 Token 不正确,则认为可能是 CSRF 攻击而拒绝该请求。
Token 一般由服务端生成(也可以由前端生成)。一般 Token 由随机字符串和时间戳组合后通过哈希运算获得,用户首次加载页面时由服务端返回给前端。显然在提交时 Token 不能再放在 Cookie 中了,否则又会被攻击者冒用。因此,为了安全起见,前端在访问后台接口时,可以把 Token 放到如下三个地方:
- URL Query
- Header
- Request Body
(4)双重 Cookie 验证。
在会话中存储 CSRF Token 比较繁琐,而且不能在通用拦截器统一处理所有接口。
那么另一种防御措施是使用双重 Cookie。利用 CSRF 攻击不能获取到用户 Cookie 的特点,我们可以要求 Ajax 和表单请求携带一个 Cookie 中的值。
双重 Cookie 采用以下流程:
- 用户访问网站页面时,向请求域名注入一个 Cookie,内容为随机字符串(例如 csrfcookie=v8g9e4ksfhw)。
- 前端向后端发起请求时,取出 Cookie,并添加到 URL 的参数中(接上例 POST https://www.a.com/comment?csrfcookie=v8g9e4ksfhw)。
- 后端接口验证 Cookie 中的字段与 URL 参数中的字段是否一致,不一致则拒绝。
此方法相对于 CSRF Token 简单了许多,可以直接通过前后端拦截的方法自动化实现。后端校验也更加方便,只需进行请求中字段的对比,而不需要再进行查询和存储 Token。
3.4 小结
CSRF 和 XSS 完全是两种不同的 Web 攻击手段,所以有着不同的应对方法。
二者的主要区别有:
- XSS 本质是 HTML 注入,和 SQL 注入差不多,而 CSRF 则是冒充用户发起非法请求;
- CSRF 需要用户登录后完成攻击,XSS 不需要。
4.防刷
为什么要防刷?
后台服务接口都应该有一个合理的请求速度,尤其对于来自真人请求的接口,如果单个用户短时间内对某个接口的请求量很大,很有可能接口被恶意强刷或客户端请求逻辑有问题。
比如 IM 应用中的加好友请求,正常用户请求频次不会超过 1/s。如果每秒钟有 10+ 次加好友的请求,那么说明接口很有可能被刷了。
接口被刷,不管是读还是写接口,都会对后台服务造成巨大压力,严重的可能会导致服务不可用。
所以,我们应该对接口做适当的限频,提早拒绝非法请求。
如何防刷?
可以通过接口限频来应对被刷。接口请求频次的统计一般有如下维度:
- 基于用户 ID
- 基于 IP
- 基于设备 ID
每个接口应该有不同的合理阈值,这个需要结合具体的业务场景来定。
这个功能为服务接口的公共功能,建议做在网关层或单独的安全层。
5.防篡改
什么是篡改?
在一次客户端与服务端的请求过程中,从请求方到接收方中间要经过很多路由器和交换机,黑客可以在中途截获请求的数据,篡改请求内容后再发往服务端,比如中间人攻击。假设在一个网上存款系统中,一条消息表示用户的一笔转账,攻击者完全可以多次将收款账号改为自己的账号后再将请求发到服务端。
为什么要防篡改?
假如客户端与服务端采用 HTTPS 协议来加密通信内容。理论上来说,HTTPS 能够防止中间人攻击,但如果黑客使用特殊手段让请求方设备使用了伪造的证书进行通信,那么 HTTPS 加密的内容也会被解密。黑客可以截获传输的数据包,进一步伪造请求进行重放攻击。
在设计接口时,我们除了使用 HTTPS 协议进行通信外,还需要有自己的一套加解密机制,对请求参数进行保护,防止被篡改。
如何防篡改?
对请求包进行签名可以有效地防篡改。
具体过程如下:
- 客户端使用约定好的密钥对传输的参数进行加密,得到签名 sign1,一般使用 HMAC
- 客户端将签名也放入请求的参数中,发送请求给服务端。
- 服务端接收到客户端的请求,然后使用约定好的秘钥对请求的参数再次进行签名,得到签名 sign2。
- 服务端比对 sign1 和 sign2,如果一致,认定为合法请求。如果不一致,说明参数被篡改,为非法请求。
因为黑客不知道签名的密钥,所以即使截取到请求数据,对请求参数进行篡改,但是却无法对请求参数进行签名。
6.防重放
什么是重放?
如果恶意用户抓取真实的接口请求包,不停地发起重复请求,这就是对接口的重放。
为什么要防重放?
接口重放一般是针对写接口的恶意请求,读接口不会有什么影响。比如发帖,发消息这种写接口,如果不防重放,会出现很多垃圾内容和骚扰消息。
什么情况下会发生重放攻击?
- 重放攻击的攻击者可以是合法的客户端,比如合法的调用方代码逻辑有问题,同一请求被循环发起了 100 次。
- 还有一种是客户端和服务端交互时被拦截了,由中间人发起了攻击。
如何防重放?
防重放的目的是不允许相同内容的请求重复发起。对于一个具体的请求,我们可以限制某个请求的生命周期,如果超过其生命周期,认定为非法,这样便起到了防重放的效果。
具体做法是:
- 客户端基于"timestamp+nonce"使用密钥计算一个签名 sign1。nonce 可以是随机数,也可以是唯一串。签名算法一般使用 HMAC。
- 客户端请求后台接口时带上 timestamp,nonce 和签名 sign1。
- 后台拿到 timestamp,nonce 和签名后,使用相同的算法计算出一个签名 sign2 与前端带来的签名 sign1 做比较,如果不一致,说明请求非法,直接拒绝。
- 如果签名一致,判断 timestamp 是否在有效时间范围内。不有效时间范围内的请求直接拒绝。
- 如果 timestamp 在有效范围内,则借助于 nonce 来进行限制。如果该账号在有效时间范围内出现过 nonce 则直接拒绝。
因为黑客不知道签名密钥,没有办法篡改时间戳和唯一/随机字符串生成新的签名。
以上做法需要注意几个问题:
- 签名计算使用的算法可能会被坏人破解。因为对于 APP 或桌面应用,坏人可以反汇编获取。
- 签名计算时使用密钥需要保存在客户端本地,可能会有泄露的风险。因为对于 APP 或桌面应用,坏人可以反汇编获取。
- 终端使用的时间戳是由后台返回的,这样防止前后端的本地时间不一致导致生成的签名。
- 不适用于 Web 应用,坏人是可以直接查看网页源码获取签名计算使用的算法和密钥。
如果要严格做到一段时间内某个请求只能被请求一次,需要对请求进行次数的统计,会用到后台存储,实现起来会复杂一点。不过一般不需要这么做。
防重放是公共功能,建议做在网关或单独的安全层。
7.防 DDoS
什么是 DDoS 攻击?
DDoS(Distributed Denial of Service)是分布式拒绝服务攻击,攻击者利用分散在各地的设备发出海量实际上并不需要的互联网流量,耗尽目标的资源,造成正常流量无法到达其预定目的地或目标服务被压垮无法提供正常服务。
举个例子会更加形象。
我开了一家有五十个座位的重庆火锅店,由于用料上等,童叟无欺。平时门庭若市,生意特别红火,而对面二狗家的火锅店却无人问津。二狗为了对付我,想了一个办法,叫了五十个人来我的火锅店坐着却不点菜,让别的客人无法吃饭。上面这个例子讲的就是典型的 DDoS 攻击。一般来说是指攻击者利用"肉鸡"对目标网站在较短的时间内发起大量请求,大规模消耗目标网站的主机资源,让它无法正常服务。因为"肉鸡"分散在各地,有分布式的特性,所以叫分布式拒绝服务攻击。
在线游戏、互联网金融等领域是 DDoS 攻击的高发行业。
为什么要防 DDoS?
DDoS 攻击带来的危害轻微的会降低目标服务的质量,增加响应延迟,严重的直接导致目标服务崩溃,无法提供服务。所以必须要防 DDoS 攻击。
常见的 DDoS 攻击有哪些?
- 网络层攻击
(1)ICMP Flood 攻击。
ICMP Flood 攻击属于流量型的攻击方式,是利用大的流量给服务器带来较大的负载,影响服务器的正常服务。由于目前很多防火墙直接过滤 ICMP 报文。因此 ICMP Flood 出现的频度较低。
(2)UDP反射攻击
DNS 反射攻击是一种常见的攻击媒介,网络犯罪分子通过伪装其目标的 IP 地址,向开放的 DNS 服务器发送大量请求。作为回应,这些 DNS 服务器通过伪造的 IP 地址响应恶意请求,大量的 DNS 答复形成洪流,从而构成预定目标的攻击。很快,通过 DNS 答复产生的大量流量就会造成受害企业的服务不堪重负、无法使用,并造成合法流量无法到达其预定目的地。
如 NTP Flood 攻击,这类攻击主要利用大流量拥塞被攻击者的网络带宽,导致被攻击者的业务无法正常响应客户访问。
- 传输层攻击
(1)SYN Flood 攻击。
SYN Flood 攻击是当前网络上最为常见的 DDoS 攻击,它利用了 TCP 协议实现上的一个缺陷。通过向网络服务所在端口发送大量的伪造源地址的攻击报文,就可能造成目标服务器中的半连接队列被占满,从而阻止其他合法用户进行访问。
(2)Connection Flood 攻击。
Connection Flood 是典型的利用小流量冲击大带宽网络服务的攻击方式,这种攻击的原理是利用真实的IP地址向服务器发起大量的连接。并且建立连接之后很长时间不释放,占用服务器的资源,造成服务器上残余连接(WAIT状态)过多,效率降低,甚至资源耗尽,无法响应其他客户所发起的链接。
(3)UDP Flood 攻击。
UDP Flood 是日渐猖厥的流量型 DDoS 攻击,原理也很简单。常见的情况是利用大量 UDP 小包冲击 DNS 服务器或 Radius 认证服务器、流媒体视频服务器。由于 UDP 协议是一种无连接的服务,在 UDP Flood 攻击中,攻击者可发送大量伪造源 IP 地址的小 UDP 包。
- 会话层攻击
(1)SSL 连接攻击。
比较典型的攻击类型是SSL连接攻击,这类攻击占用服务器的SSL会话资源从而达到拒绝服务的目的。
- 应用层攻击
(1)HTTP Get 攻击。
和服务器建立正常的 TCP 连接之后,不断地向后端服务接口发起 Get 请求,压垮后台服务。这种攻击的特点是可以绕过普通的防火墙防护,可通过 Proxy 代理实施攻击。
(2)UDP DNS Query Flood 攻击
UDP DNS Query Flood 攻击采用的方法是向被攻击的服务器发送大量的域名解析请求,通常请求解析的域名是随机生成或者是网络世界上根本不存在的域名。域名解析的过程给服务器带来了很大的负载,每秒钟域名解析请求超过一定的数量就会造成DNS服务器解析域名超时。
如何防 DDoS?
DDoS 防御是保障系统安全运行的必要举措,虽然不属于服务接口层面需要考虑的事情,但是知道相关的防御措施还是很有必要的。
防御 DDoS 攻击的策略方法,包括但不限于:
(1)定期检查服务器漏洞。
定期检查服务器软件安全漏洞,是确保服务器安全的最基本措施。无论是操作系统(Windows 或 Linux),还是网站常用应用软件(MySQL、Apache、Nginx、FTP 等),服务器运维人员要特别关注这些软件的最新漏洞动态,出现高危漏洞要及时打补丁修补。
(2)隐藏服务器真实 IP。
通过CDN节点中转加速服务,可以有效的隐藏网站服务器的真实IP地址。CDN服务根据网站具体情况进行选择,对于普通的中小企业站点或个人站点可以先使用免费的CDN服务,比如百度云加速、七牛CDN等,待网站流量提升了,需求高了之后,再考虑付费的CDN服务。
其次,防止服务器对外传送信息泄漏IP地址,最常见的情况是,服务器不要使用发送邮件功能,因为邮件头会泄漏服务器的IP地址。如果非要发送邮件,可以通过第三方代理(例如 sendcloud)发送,这样对外显示的 IP 是代理的 IP 地址。
(3)关闭不必要的服务或端口。
这也是服务器运维人员最常用的做法。在服务器防火墙中,只开启使用的端口,比如网站 Web 服务的80端口、数据库的 3306 端口、SSH 服务的 22 端口等。关闭不必要的服务或端口,在路由器上过滤假IP。
(4)购买高防服务器提高承受能力。
该措施是通过购买高防的盾机,提高服务器的带宽等资源,来提升自身的承受攻击能力。一些知名 IDC 服务商都有相应的服务提供,比如阿里云、腾讯云等。但该方案成本预算较高,对于普通中小企业甚至个人站长并不合适,且不被攻击时造成服务器资源闲置,所以这里不过多阐述。
(5)限制 SYN/ICMP 流量。
用户应在路由器上配置 SYN/ICMP 的最大流量来限制 SYN/ICMP 封包所能占有的最高频宽。这样,当出现大量的超过所限定的 SYN/ICMP 流量时,说明不是正常的网络访问,而是有黑客入侵。早期通过限制 SYN/ICMP 流量是最好的防范 DOS 的方法,虽然目前该方法对于 DDoS 效果不太明显了,不过仍然能够起到一定的作用。
(6)黑名单。
对于恶意流量,将 IP 或 IP 段拉黑。
(7)DDoS 清洗。
DDoS 清洗会对用户请求数据进行实时监控,及时发现 DOS 攻击等异常流量,在不影响正常业务开展的情况下清洗掉这些异常流量。
(8)CDN 加速。
CDN 指的是网站的静态内容分发到多个服务器,用户就近访问,提高速度。因此,CDN 也是带宽扩容的一种方法,可以用来防御 DDoS 攻击。
8.小结
道高一尺,魔高一丈,没有绝对的安全,我们能做的就是尽可能地提高坏人作恶的门槛,让我们的系统变得更加安全可靠。
参考文献
Securing APIs: 10 Ways to Keep Your Data and Infrastructure Safe
前端安全系列(一):如何防止XSS攻击? - 美团技术团队
前端安全系列(二):如何防止CSRF攻击? - 美团技术团队
Cookie 的SameSite 属性- 阮一峰的网络日志
SameSite cookie 属性- Teams - Microsoft Docs
SQL注入攻击常见方式及测试方法 | CSDN博客
API接口设计:防参数篡改+防二次请求 | 腾讯云
什么是 DDoS 攻击?| 知乎
DDoS 攻击是什么? 如何防止DDos攻击?| SegmentFault