常见的 Web 攻击与防范
今天我们来聊一聊常见的 Web 安全相关的问题,也会在接下来的一节中说一说 Django 在 Web 安全方面做了哪些工作。了解了这些才有可能防范出现一些低级的安全问题,避免给开发的项目留下十分明显的安全隐患。当然,完美的应用肯定是不存在的,都会有未被发现的漏洞,我们在开发中只需要保证不要出现太过于明显的问题即可。
1. DDoS攻击
全称 Distributed Denial of Service,中文意思为“分布式拒绝服务”,就是利用大量合法的分布式服务器对目标发送请求,从而导致正常合法用户无法获得服务。DDoS 攻击方式简单粗暴,可以达到直接摧毁目标的目的。
另外,相对其他攻击手段 DDoS 的技术要求和发动攻击的成本很低,只需要购买部分服务器权限或通过技术手段控制一批肉鸡即可。另一方面,DDoS 具有攻击易防守难的特征,服务提供商为了保证正常客户的需求需要耗费大量的资源才能和攻击发起方进行对抗。这些特点使得 DDoS 成为黑客们手中的一把很好使的利剑,而且所向披靡。
DDos 的攻击形式多种多样,有针对资源消耗类攻击、服务消耗性攻击、反射性攻击、混合型攻击等等,最终达到对端服务不可用的目的。
互联网发展至今,DDoS 攻击就一直存在,而且随着技术的发展,DDoS 的攻击方式也变化多端。目前而言,对于 DDoS 攻击仍旧是一个令人头疼的问题,许多创业公司或者规模较小的公司,不愿过多投入到防御体系的建设上,这就导致大部分公司面对高流量的 DDoS 攻击时都是直接投降,毫无还手之力。
目前,安全产业对 DDoS 的防护系统本质上是一个基于资源较量和规则过滤的智能化系统,主要的防御手段和策略包括:
- 资源隔离
- 用户规则
- 大数据智能分析
- 资源对抗
随着目前人工智能和深度学习技术的火热发展,在 Web 安全领域已经开展了许多关于这方面的实践研究,也相信不久的将来,DDoS 攻击能彻底被深度学习技术打败,不再成为大部分业内公司的噩梦。
2. CSRF攻击
CSRF(Cross-site request forgery),中文名称:跨站请求伪造。可以这么简单理解CSRF攻击:攻击者盗用了你的身份(获取登录正规网站的 cookie 信息), 并以你的名义发送恶意请求(比如转账、提交订单等)。CSRF 主要会导致个人的隐私泄露并威胁财产安全。我们用下面一幅图来描述一下 CSRF 攻击的形成与危害:
从上面的示例过程可以看出,要完成一次 CSRF 攻击,受害者必须依次完成两个步骤:
- 登录受信任网站A,并在本地生成Cookie;
- 在不登出A的情况下,访问危险网站B;
上面这几种情况看似很难一起发生,但在现实场景中却是很容易发生的。这主要是基于以下几个原因导致的:
-
我们往往登录了一个网站后,打开多个 tab 页面去访问多个其他网站,类似于下图:
-
关闭浏览器了后,本地的 Cookie 并不会立即过期,上次会话也并不意味着结束,除非我们点击登出(logout)或者主动清除浏览器缓存;
-
所谓的危险网站,可能是经常被人访问的正规网站。该网站由于存在某种漏洞被人恶意攻击,并在网站中放入恶意链接诱导用户点击;
基于以上三点,CSRF 攻击很可能每天在我们身边上演。但是网站必须要确保不存在相应的 CSRF 漏洞,否则极容易黑客攻击。
关于 CSRF 攻击的主要防御手段便是在网页上添加一个随机的校验 token 值。由于 CSRF 的本质在于攻击者欺骗用户去访问自己设置的地址,所以如果要求在访问敏感数据请求时,要求用户浏览器提供不保存在 cookie 中,并且攻击者无法伪造的数据作为校验,那么攻击者就无法再执行 CSRF 攻击。这种数据通常是表单中的一个数据项。服务器将其生成并附加在表单中,其内容是一个伪乱数。当客户端通过表单提交请求时,这个伪乱数也一并提交上去以供校验。正常的访问时,客户端浏览器能够正确得到并传回这个伪乱数,而通过 CSRF 传来的欺骗性攻击中,攻击者无从事先得知这个伪乱数的值,服务器端就会因为校验 token 的值为空或者错误,并拒绝这个可疑请求。
3. XSS攻击
XSS 攻击又称 CSS,全称Cross Site Script (跨站脚本攻击),其原理是攻击者向有 XSS 漏洞的网站中输入恶意的 HTML 代码,当用户浏览该网站时,这段 HTML 代码会自动执行,从而达到攻击的目的。
XSS 攻击可以分成两种类型:
- 非持久型 XSS 攻击:顾名思义,非持久型 XSS 攻击是一次性的,仅对当次的页面访问产生影响。非持久型 XSS 攻击要求用户访问一个被攻击者篡改后的链接,用户访问该链接时,被植入的攻击脚本被用户游览器执行,从而达到攻击目的;
- 持久型 XSS 攻击:持久型 XSS,会把攻击者的恶意代码数据存储在服务器端,攻击行为将伴随着恶意代码的存在而一直存在。
XSS 的攻击防范主要是对提交的各种字符串数据进行校验,避免出现可执行的前端代码。主要的防范措施有:
- 对输入内容的特定字符进行编码,例如表示 html 标记的 < > 等符号;
- 对重要的 cookie 设置 httpOnly,防止客户端通过
document.cookie
读取 cookie,此 HTTP 头在服务端设置; - 将不可信的值输出 URL 参数之前,进行 URLEncode 操作,而对于从 URL 参数中获取值一定要进行格式校验;
- 不要使用
eval
来解析并运行不确定的数据或代码,对于 JSON 解析可使用JSON.parse()
方法; - 后端接口也要对关键的字符进行过滤,防止将恶意的脚本代码保存到数据库中。
4. SQL注入攻击
SQL 注入是网站存在最多也是最简单的漏洞,主要原因是程序员在开发用户和数据库交互的系统时没有对用户输入的字符串进行过滤,转义,限制或处理不严谨,导致用户可以通过输入精心构造的字符串去非法获取到数据库中的数据。SQL 注入是一种注入攻击,可以执行恶意 SQL 语句。它通过将任意 SQL 代码插入数据库查询,使攻击者能够完全控制 Web 应用程序后面的数据库服务器。攻击者可以使用 SQL 注入漏洞绕过应用程序安全措施;可以绕过网页或 Web 应用程序的身份验证和授权,并检索整个 SQL 数据库的内容;还可以使用 SQL 注入来添加,修改和删除数据库中的记录。有一个经典的例子如下:
一个网站后台管理系统存在 SQL 注入漏洞。它使用 url 传递的参数 username 和 password 去数据库校验对应的用户名和密码是否正确,形成的 SQL 语句如下:
SELECT * FROM user WHERE username='admin' AND password='passwd'
如果后台服务对输入的用户名和密码做任何处理,前台直接构造用户名为:’ or 1=1#。此时后台形成的查询 SQL 语句为:
SELECT * FROM user WHERE username='' or 1=1#' AND password='xxx'
这条语句也是可以执行的,而且可以得到所有的用户记录。因为 “or 1” 让 SQL 的查询条件永远为 True,而 ‘#’ 屏蔽了后面的密码校验。
早期这种后台管理系统的漏洞屡见不鲜。很多人只需要通过黑客工具找到存在 SQL 注入漏洞的后台管理系统,然后使用这个万能密码就能直接进入网站的管理系统页面,达到入侵的目的。
SQL 注入攻击方式主要有以下三种:
- 带内注入:攻击者可以通过相同的通信通道发起攻击并获得结果,主要通过以下两种方式完成。
- 基于错误的SQL注入:从显示的错误消息中获取有关数据库的信息
- 基于联合的SQL注入:依赖于攻击者能够将UNION ALL被盗信息的结果与合法结果连接起来
- 盲注入:也称为推理SQL注入;
- 带外注入:攻击者通过精心制作的 SQL 语句注入到数据库,可以触发数据库系统创建与攻击者控制的外部服务器的连接。通过这种方式,攻击者可以收集数据或可能控制数据库的行为。
对于 SQL 的注入攻击,在开发 Web 系统时只需要遵循以下几点建议,就能避免绝大部分的 SQL 注入漏洞了:
- 避免将用户提供的输入直接放入 SQL 语句中,最好使用准备好的语句和参数化查询;
- 不要将敏感数据保留在纯文本中;
- 限制数据库权限和特权;
- 避免直接向用户显示数据库错误。大部分的时候,我们需要拦截相关异常,然后定制化输出数据库异常信息;
- 对访问数据库的Web应用程序使用Web应用程序防火墙(WAF);
- 及时更新数据库至最新版,防止黑客利用旧版本漏洞发起攻击。
5. 小结
本小节中我们详细介绍了 Web 攻击的几种常见方式以及相应的防范手段。服务器上任何一个应用的漏洞都有可能是黑客攻陷服务器的突破口。笔者之前在公司内部部署 saltstack 运维管理系统时,不小心让 saltstack 中的 API 服务也对外可访问(服务启动以 0.0.0.0 的方式),而由于 saltstack 自身的漏洞原因导致被人扫描并借助该服务向服务器内部植入了病毒,导致我们主机卡顿、并被病毒占用大量带宽,对外发送数据。最后不得已,只能重装系统,浪费了几天时间在重装所有应用和服务上,教训惨痛,当切记切记!