技术员的安全修养

Table of Contents

最后更新:2019-02-21

1 邮箱选择

  • 选择口碑较好的邮箱,比如腾讯、Gmail。口碑源于厂商对待安全事故处理的态度上。
  • 按用途使用多个邮箱
  • 个人域名邮箱

对于个人域名邮箱,我比较喜欢把 admin@xxx.com、root@xxx.com 送给别人使用,倘若遇到被人社工,这或许能让黑客迷失方向。曾经有人在被泄露的密码库中找到我送别人用的管理邮箱,让他社工错了方向。

2 密码安全

  • 测试环境和生产环境密码不要一致
  • 避免弱口令密码
  • 使用 leet 密码
  • 可使用密码管理软件,如 1password

3 安全开发

  • 测试环境也需要安全措施,如数据库有较强的密码、不要任何人可访问测试环境
  • 开发机、测试环境不要随便监听 0.0.0.0,尤其是一些在做 Web 开发时会监听 0.0.0.0(尤其注意咖啡厅等公共环境),这样内网其他机器很轻松就访问到,开发中的代码可能安全性并不高。
  • 安全也是需求。在制定项目需求、做架构设计时,应当把安全也考虑进去,如:密码加密存储、后台不可外网访问、授权机制、操作日志记录等。
  • 将安全引入开发环节中。不过这对团队要求相对较高一些,依赖团队是否有懂安全的人。如:制定安全编码规范、代码 review 时做安全审计、在测试环境中做黑盒渗透测试、上线后做渗透测试等。

3.1 安全需要全面,攻击只要一个点

一名有安全经验的开发者和攻击者,谁处上风?我认为是攻击者,对于攻击者而言,只要找出一个攻击点,就可能让整个防御防御崩塌;而对于开发者而言,他所需要考虑更全面,是整套系统各环节的安全。

一套程序的安全并不单单由这套程序的源码质量决定,所用的操作系统、平台、硬件、框架、第三方库、编程语言、编译器等等都跟安全挂钩,比如一套系统逻辑设计很严谨,所用的编程语言却存在难以费解的特性而造成安全问题。一个开发者不可能有精力去这么全面地熟悉这所有技术并考虑周全。

所以,在安全中没有银弹,安全是一个持续的过程,只有不断地学习。

3.2 编码安全

虽然有资料调查称开发人员参与了安全编程培训半年之后,有90%的内容都会忘记,但还是提供一些指导方向:

  • 学习安全知识,至少掌握常见的攻击方式,如 SQL 注入、XSS 等
  • 任何输入都有可能有问题、任何输出也可能有问题,不要绝对信任输入和输出
  • 函数单一原则,不要做功能本身以外的事情
  • 需要权限认证的地方,一定要做好权限控制
  • 用户的密码加密存储
  • 不使用来路不明、无人维护的框架和库
  • 代码架构明确,不要养成 copy and paste 习惯,若一段代码出了安全问题,但代码分散严重,可能会修复不完整

3.3 引入安全流程

软件开发流程主要包括:需求分析、架构设计、功能实现、测试。

完全可以将安全穿插到整套流程中的各个环节中,比如:

  • 做需求分析时,“安全”也作为需求,如密码要求加密存储、系统中帐号需要有角色划分、对用户的关键操作有日志记录功能;
  • 做架构设计时,要考虑到整体架构中,哪些是需要安全保护的,比如后台不放在公网可访问的地方、数据库有 IP 访问限制、加密传输等等;
  • 功能实现时,具体关注点在各种常见漏洞的防御,可以考虑在 code review 时,除了做代码质量评审外,同时也做安全评审,以及在开发过程中使用安全增强风格的工具,对代码进行审查;
  • 测试时考虑一些扫描器自动扫描、黑/白/灰盒测试;
  • 产品上线后引入红队测试、日志分析。

敏捷开发也好,安全开发也好,一定要弄清楚一个观念——流程是建立在技术团队的技术过关基础上的。如果一个团队还存在技术问题(比如完全不懂安全),引入这些流程也发挥不出应有的效果。

4 正确使用安全产品

有很多公司听了安全厂商的夸大宣传,会把整体的安全依赖在某些安全产品上,这是很大的问题,比如:

  • 安全产品能力有限,不保护得了所有范围,最大的问题还是人;
  • WAF、防火墙等安全产品是在本身安全的情况下增加的附加东西,如果产品本身就存在安全问题,仍然保护不了自身;
  • 很多安全产品本身也有安全问题。

安全产品只能一定程度上提高攻击的成本,但无法完全阻止攻击,所以要正确使用安全产品,而不是去完全依赖它。

5 警惕版本控制

  • 不要将 Git 的 user.name 和 user.email 全局设置为公司或团队的帐号

避免被社工。当新项目做 git init 初始化时,手动设置 user.name 和 user.email。有很多人将这些信息设置为全局的,当在 Github 上提交自己的项目时,就会不小心泄露公司邮箱。

  • 注意配置文件、代码中是否泄露敏感信息

比如公司内网服务器地址、数据库权限、内网验证服务器、私钥、API key 等信息。

  • 勿将 shell 配置文件(如 ~/.bashrc)、Emacs/Vim 配置、~/.ssh 等上传到仓库中
  • push 代码时,多看看 diff,清楚所有的变更

有一些黑客在渗透了别人开发服务器时,会在代码中插入后门,当代码 push 到仓库后,并且部署在生产环境中时,后门也同时生效。

6 容器、虚拟机和软件镜像

  • 避免来源未知的 Docker 镜像、虚拟机镜像,因为你不知道镜像中安全情况,尤其是不要部署在生产环境。
  • 虚拟机中不要用常用密码和证书。人们通常用虚拟机做测试或学习使用,往往忽视了虚拟机的安全,认为外界是无法接触的,一旦不小心让虚拟机从外界可访问(比如在同一网络环境中),那么虚拟机就是安全的短板。你放在虚拟机中的配置文件、证书以及系统密码,都有可能被黑客拿走。

6.1 软件镜像

上面说到避免来源未知的 Docker 镜像,这个原则也适用于其他软件镜像,在下载安装的时候有确认合法性吗?建议参考这篇文章:《被忽视的攻击面:Python package 钓鱼》

7 养马甲

  • 至少一个马甲邮箱
  • 至少一个马甲 QQ
  • 可以考虑马甲手机号

8 社工自己

善用搜索引擎搜索你的密码、邮箱、QQ 等。

一个例子: 2011年时在淘宝充值过优酷会员(需要提供密码),不久之后出现了大量观看记录,然后在 Google 中搜索我密码,发现店主把我的优酷帐号当作免费福利发到他自己论坛上。

9 日常习惯

  • 离开后锁屏电脑
  • BIOS 加密
  • 重要资料加密存储,如使用 VeraCrypt
  • 使用正版操作系统。2005年有个叫“电脑公司特别版 Windows XP”的盗版系统,自带一个叫“new”的管理帐号,系统默认开启远程桌面。用扫描器扫 B 段 IP,一个下午最多可以收获百余台肉鸡。
  • 善用虚拟机运行来路不明的软件和解压压缩包

10 资产管理

当零日漏洞爆发时,哪些地方需要升级?

你要清楚你或你们团队的软件资产,比如:有多少台服务器、服务用的什么操作系统、部署了哪些环境(如 Java、WordPress?)、部署了什么服务(Nginx?Tomacat?等等)、业务代码中用了哪些三方组件。

开发团队中,应当清楚了你们的软件资产,才能在爆发漏洞时做出更及时的响应。

一旦公司规模变大、业务变多时,不注重软件资产管理,就会在漏洞爆发时失控。举个简单的例子:Strust2 远程代码执行漏洞爆发时,一个大公司的运维升级了线上主要的业务,但却不知道哪些团队同样也用了Strust2(选用 Strust2 的原因往往是公司层面的技术选型要求)在外网环境,所以并且没有及时做更新,导致出现安全问题。

案例:

《我是如何轻松拿到Google $1337现金奖励的》

10.1 个人资产

当新闻曝光许多互联网大厂商被拖库时,作为个体的我们,应该及时修改密码。修改完密码以后还要考虑这个密码是否有在其他地方使用过?此时你的密码已经不安全了,尤其是部分厂商采用明文存储密码,并被黑客窃取。

密码是我们个人的主要资产,发生安全威胁时哪些地方的帐号需要修改?绝大多数的人无法准确排查完,因为很多人没有管理自己的密码资产。

我对公司某同事进行社工过,只用了他的名字在 Google 搜索,就成功进入了他的代码仓库、邮箱、OA 等。方法很简单,就是利用了网上泄露的密码库。

建议使用 KeepPass 一类的密码管理软件管理好自己的密码,并且尽可能不要用太通用的密码。

个人资产,还包括了重要的文件、代码等,必要的应当加密存储,使用诸如 VeraCrypt 一类的加密软件。

还有我们用的操作系统、安装的常用软件等,都是个人软件资产。

11 选用三方软件/库的原则

  • 谨慎不了解的插件,很多安全问题就出现在插件上,如 WordPress 的插件
  • 选用安全性较高的程序(如 WordPress)
  • 避开小众程序,除非自己有能力修补漏洞
  • 选用的组件有专业团队维护
  • 及时更新

12 很重要的防御技术

  • 加密:加密是安全中最重要的技术,它保障了数据的完整性和机密性。比如使用 SSL 加密通信、数据加密存储。
  • 日志:主要的平台或程序应具有日志功能,日志不仅用于分析 bug、异常,若是出现安全事故,也便于跟踪调查。根据这些年的日志分析经验,日志的关键信息包括:时间、用户、客户端 IP 地址,以及做了什么操作。
  • 备份:防御始终是处于被动状态,不管是黑客入侵也好、网管跑路也好、或者数据误删,一旦造成了数据丢失等情况,应当有完善的备份系统可帮助恢复数据。