Skip to content

Latest commit

 

History

History
205 lines (108 loc) · 9.27 KB

03.md

File metadata and controls

205 lines (108 loc) · 9.27 KB

第三章:服务的架构一定有漏洞(上)

相较前两章,这一章的内容就相对温和许多了。服务的架构一定会有漏洞,这都是大家心知肚明的事。

反而没什么好吃惊的。

这一部分我会拆成几个章节写。这一章主要是在讲「暴露在外的部分」

状况一:扫描攻击

关于网站的部分,最常见的攻击有几种:

  • XSS 攻击:盗取用户 cookie
  • SQL Injection:存取数据库,捞取资料,窜改数据
  • Directory Traversal Attack:摸清机器档案目录,甚至获取机器权限 等等....

诸如此类的攻击手法,我在这本书里面就不讲得太详细了。

关于此类的内容,在 OWASP 里面有非常非常多的内容。如果你对于这些常见扫描攻击陌生,建议去读读 OWASP 出的一些指南。

http://www.owasp.org.cn/owasp-project/secure-coding

这本书我想讲的是解法、防御。

解法:

这些基础漏洞,主要出自于语言、框架,或者是低阶程序员的疏失。有几个方向你可以进行。

  1. 安装代码扫描工具

我自己擅长的是 Rails 框架上的项目开发,Rails 的开发观念以及第三方生态相对于完善。框架自带 XSS 防御、 SQL Injection 防御、XSRF 防御。如果硬要在里面写出不安全的代码,得程序员硬干 override 才能办到。

至于 Rails 界有一套服务叫 codeclimate,除了扫描代码质量,也可以扫描可能可能出现漏洞的代码。

另外,也有一套服务叫 sqreen,这套服务能充当 WAF,自动阻拦可疑扫描,并且追踪所有 rubygems 的更新与 security patch,当架构上的第三方库太老旧或是有安全疑虑,系统会自动通知开发者需要更新。

  1. 雇用白帽黑客、 资安谘询公司

安装代码扫描工具,可以很大程度防御与过滤一般的「机械式攻击」。

但「机械式」攻击,不是一般互联网服务最大的威胁。而是黑客的「手工攻击」。

机器是死的,人是活的。

如果你的服务非常重要,保卫著许多人的资产。我建议还是雇用正统资安谘询公司,人工灰盒审计(等于是请资安顾问对自己的公司实施各种攻击,找到所有可能性的攻击与脆弱点,出具报告修复)一次。而且这个灰盒审计得定期执行。

状况二:后台攻击

第二种状况,是针对「后台合法攻击」。

什么是针对后台合法攻击呢?我在这里揭露一个事实吧:

许多服务的架构都是这样设计的,后台只可能在两个地方:

  • example.com/admin
  • admin.example.com

命中率高达 99%。

而且呢,在外网就能够存取。

也就是如果你的其中一位客服或员工被猜到密码,这套服务马上就沦陷。而且因为是正常操作,不会触发任何警报。

解法:

首先,这个架构有几个地方需要改变。当然有时候你的财力物力不一定马上可以做到。但起码可以降低相当大的风险。

  1. 改名,换网域

绝对不能叫

  • example.com/admin
  • admin.example.com

你可以叫

example.cc/admin

或者

a.example.cc

至少不那么好猜,以及防御黑客盗到员工 cookie 就能打进来。

  1. 限制存取来源

这里有一个小细节,example.cc 不能是真实网域,得是一个你虚构的域名。唯有修改 /etc/hosts 才能正确的 mapping。

这样避免了被猜到域名,直接在公开网段上被存取得知的可能性。

再来,将该机器限制只能从特定 IP 连线,也就是员工必须要使用 VPN 或者是办公室才能连入。

当然最好的情况是将 admin 放在内网里面,当然如果短时间作不到,这也是一个暂时可以接受的 workaround。

  1. 读写分离

什么叫读写分离呢?也就是 admin 与 public service 是两套服务。public service 是给用户的服务,用户只能读以及有限的改写自己有权限改的资料(比如个人 profile 等等)

而 admin 的代码,是跑在另外一份机器上与另外一份架构上。这些「写」「变更」的部分是与用户接触的服务完全阻隔开来。

  1. Log 机制

因为资料变更写入通常会造成安全性。所以有几个机制需要加入设计:

  1. 网站只能做软删除,而不允许硬删除操作。
  2. 任何操作都要记录 Log,谁在什么时候,做了某事。并打到 slack 进行记录通知。做多重 Log 备份。
  3. 关键操作,需要三重确认,多人签名,放行机制审核。

状况三:数据窜改攻击

大家的服务都是暴露在互联网上的。这里有一个危险但真实的思路。黑客极有可能直接打进 service,合法的用 web shell,操作数据库改数据。

这边我翻译成白话:以币所的情况就是骇客直接改数据库,改成自己馀额有100颗 BTC,然后合法提走。

如何防御这样的攻击呢?

  1. 建立历史变动记录

互联网实做点数与储值系统都是直接更改「最后馀额」。

而相对安全的架构是:将帐号馀额做版本控制,就是经过「合法操作」的加扣馀额都会被纪录。如果当下馀额,与帐号的历史版本不一致,那么这笔纪录就是「伪造的」。

而在进行任何馀额上的合法变动(如买卖,提领,兑换)等等的操作,都必须再次验证过去历史数据是否匹配,若为伪造,该个帐号会立刻被冻结。

  1. 数据验证

分个人与全站。

一个个人有无数笔的帐号版本,但对到最后,应与当下馀额一致。

全站资产,站上也就是比如站上的应有多少 BTC,经过变动以后应该还是应有相对应的 BTC。

每几个小时扫描一次。只要发现异常,立刻冻结与 slack 与简信发出警告。

  1. 建立行为白名单与黑名单

内部风控可以先自我列出什么是「不可能」的「状况」。直接写入风控系统。

比如说「注册一两天」的新帐号,立刻要提领超过 10 颗比特币。(洗钱或盗号嫌疑)

或者已经超过 60 天没有登入,突然间登入,登入后两分钟内马上要提空馀额。(盗号嫌疑)

真实状况不是不可能没有。只是看起来「可疑」。

而这一类的「可疑行为」。一律 delay 动作或冻结,进人工审核处理。

针对站上的用户,建立分级评分机制。按照风控分数自动锁定与放行。

状况四:服务器被入侵潜伏

有一些黑客,入侵服务器后,并不急著马上「下手」。

而是潜扶在机器里面,跑后门。「传资料」回去,这些资料包括但不限于「数据库密码」「使用者数据」「其他机器的 ip 清单」「管理员的密码」等等等等….

有几个方向可以防范与侦测:

  1. 不正常的流量

数据库往往非常庞大。为了将数据库运走,往往会产生「不正常」的流量与使用量。

  1. 防火墙白名单

只准机器被连某些 port,而不准机器连外

  1. 管理员登入 log

管理员登入机器,必定发送 log 到 slack,且 cc 管理员群。

  1. 使用「容器」部署

一台机器如果你发现被入侵,虽然没有造成实质损坏,但这一台服务器绝对不能再上线。以免有什么你不知道的后门等等。

比较好的方式,是一开始就用容器如 Docker 架构部署。机器从 OS/ 套件 / 代码都是 script 自动拼组而成的。

而不是手工安装的。摧毁被污染的服务器时,成本才不会过大。

状况五:以前已经修好的 bug,某次代码修改后又不小心打开了

一个互联网服务是活的。我们不能强求一个服务是绝对安全绝对没有 bug 的。但起码要是相对安全的。

有一些状况是之前这个 bug 被修复了。但是在几个月后,因为其他机制的引入,bug 又被打开了。

这里你可以引入一个架构概念,叫 security as test。就是写 integration test,将入侵手法的行为写成 test。确保代码更动时,这个 bug 不会被触发。

总结

关于架构的潜在问题还有很多,在此我只列出最常见的五个情形。

这里面的思维我想强调一个概念,就是绝对的安全是不存在的。你的程序员也不可能阻挡所有的攻击。毕竟程序员的思路主业是「建设」。黑客的思路主要是「破坏窃取」。

而攻击往往比较简单。而身为架构建设者,在规划改善这些架构时你的思路应该是,我如何用 20% 的精力,做到 80% 的风险管理。

所谓「风控」,这个字包含了风险管理和风险控制。

风险管理,它是指如何在项目或者企业在一定的风险的环境里,把风险减至最低的管理过程。它的基本程序包括风险识别、风险估测、风险评价、风险控制和风险管理效果评价等环节。

风险控制是指风险管理者采取各种措施和方法,消灭或减少风险事件发生的各种可能性,或者减少风险事件发生时造成的损失。

这里总结一下你现在可以主动做的事:

  1. 如何大规模的技术性降低风险?你可以安装什么服务,一次性大幅上升公司的防御能力。
  2. 如何避免「一个人」被渗透,就会产生大规模的损失?关于人类的弱点是什么?
  3. 最脆弱的数据环节在哪里?如何自动校验这件事?
  4. 如何自动化防范过去的错误不再发生。