做 Web 开发必备的安全核对清单

如果能按照本文的这个清单来实践,就能将网络安全方面的风险降得很低。

Web开发人员安全清单

在云端开发安全又健壮的 Web 应用非常难。如果你认为这很容易,那你技术水平要么已经很牛叉,要么还没有踩过坑。

如果你盲目接受最简可行产品(Minimum Viable Product,简称 MVP),并且认为你能在一个月之内创建一个既有价值又安全的产品,那么在你推出你的“产品原型”前,你还需要多想想。在你查看了下面的清单之后,确认你不会犯这些严重的安全问题。至少,你要对你的潜在用户坦诚,让他们知道你还没有一个完整的产品,并且只提供一个没有全面安全的原型。

这个清单很简单,并且也不是那种大而全的。我已经开发安全的 Web 应用有 14 年多了。这个清单包含了一些相对重要的问题。这些问题都是我在这段时间学到的,而这个过程也是痛苦的。当你在创建 Web 应用时,我希望你能够认真地对待这些问题。

 

如果在这个清单中,你有我没有提到的项目,请留言补充。

数据库

  • [ ] 可以识别用户的数据和敏感数据(如访问令牌、电子邮件地址或账单信息)需要加密。
  • [ ] 如果你的数据库在休息状态时支持低成本加密(如AWS Aurora),那么启动该功能来保护硬盘上的数据。同时也要确保所有备份都是被加密存储的。
  • [ ] 给用户最低访问权限的账户。不要使用数据库的 root 账户。
  • [ ] 刻意设计一个密钥库,用它存储和分发机密内容。不要硬编码到你的应用中。
  • [ ] 通过只使用 SQL 预处理语句(prepared statements)的方法来完全防止 SQL 注入。比如:如果要使用 NPM,不要使用 npm-mysql,而是使用 npm-mysql2,因为它支持预处理语句。

开发

  • [ ] 对于每个发布的版本,确保软件的所有组件都通过了漏洞扫描。组件指的是操作系统、库和包。这应该自动地进入持续集成/持续交付流程。
  • [ ] 保证开发系统的安全。同样的,对于你使用的产品系统,也需要保持相同的警惕。在安全、隔离的开发系统中开发软件。

认证

  • [ ] 确保所有密码都经过合适的加密方法(如 bcrypt )的散列处理。永远不要自己实现加密方法,并且用好的随机数据来正确地初始化加密方法。
  • [ ] 在实现登录、忘记密码、密码重置等功能时,用经过验证过的最佳实现或组件。不要重复造轮子,因为你很难保证其在所有场景中都不会出现问题。
  • [ ]遵循简单且合适的密码规则,鼓励用户使用较长的随机密码。
  • [ ] 你们提供的所有服务,用多重认证来验证登录。

拒绝服务防护

  • [ ]确保网站不会因 API 遭拒绝服务攻击(DOS)而瘫痪。至少,在相对较慢的 API 路径上(像登录和 Token 生成程序)设置频率限制器。
  • [ ] 对用户所提交的数据和请求,在大小以及结构这两点上执行合理的限制。
  • [ ] 通过使用全局缓存代理服务(类似 CloudFlare )来规避分布式拒绝服务(DDOS)。如果网站遭到 DDOS 攻击,你就能打开这个服务和其他类似的,以作 DNS 查询。

网络流量

  • [ ] 整个网站都使用 TLS,不仅仅是登录表单和响应。 永远不要只在登录表单中使用 TLS。
  • [ ] Cookie 必须设置 httpOnly、安全、被路径和域限定。
  • [ ] 使用内容策略安全(CSP),并且不允许 unsafe-*(*是通配符)后门。虽然配置时很痛苦,但这是值得做的。
  • [ ] 在客户端的响应头中使用 X-Frame-Option、X-XSS-Protection。
  • [ ] 使用 HSTS 响应强制仅限 TLS 访问。在服务器上重定向所有 HTTP 请求到 HTTPS,作为替代方案。
  • [ ] 在所有的表单中使用 CSRF 令牌(Token)。使用新的 SameSite Cookie 响应头,这彻底解决了所有较新浏览器上的 CSRF 问题。

API

  • [ ] 确保公开 API 中没有可枚举的资源。
  • [ ] 确保用户经过全面的认证,并且拥有适当权限的用户才能访问 API。
  • [ ] 在 API 中使用随机检查,以检测潜在攻击的非法或异常请求。

验证

  • [ ] 为了给用户快速的反馈,可以在客户端做输入合法性验证,但是永远不要相信用户的输入数据。
  • [ ] 在服务器端使用白名单,来验证所有用户的输入。永远不要直接将用户的内容添加到响应中。永远不要在 SQL 语句中使用用户输入的内容。

云配置

  • [ ] 确保所有的服务打开尽可能少的端口。当隐晦式安全(security through obscurity)没有保护的效果时, 将默认的端口替换成非标准的端口,这样可以让攻击者更难攻破。
  • [ ] 将后端数据库和服务托管到私有 VPC 上 (虚拟私有云),而 VPC 不能被任何公共网络访问。当你在配置 AWS 安全组和对等 VPC 时,你需要非常仔细,因为这可能导致服务无意中对外部开放。
  • [ ] 在隔离 VPC 和对等 VPC 里隔离逻辑服务,以便支持跨服通信。
  • [ ] 确保所有服务接收的数据,来自于一个尽可能小范围内的 IP 地址。
  • [ ] 限制出站 IP 和端口流量,最大限度地减少 APT 攻击带来的损失和“通讯”。
  • [ ] 始终使用 AWS 访问管理(IAM)这个身份,而不是 root 凭据。
  • [ ] 授予所有操作和开发人员最小的访问权限。
  • [ ] 根据时间表定期地更换密码和访问密钥。

基础设施

  • [ ] 确保你能在不停机的情况下升级。确保你能通过完全自动的方式快速升级。
  • [ ] 使用像 Terraform 这样的工具创建所有的基础架构,而不是通过云端控制台。基础架构应该被定义为“代码”,并且能够按下按钮来重建。对于任何在云端手动创建的资源采取零容忍态度,之后 Terraform 就能审计你的配置了。
  • [ ] 所有服务都使用集中式日志架构。你永远都不应该需要 SSH 来访问或者检索日志。
  • [ ] 除了一次性诊断,不要通过 SSH 连接到你的服务。通常使用 SSH 意味着你没有自动执行重要任务。
  • [ ] 永远不要在任何 AWS 服务组上保持 22 号端口为打开的状态。
  • [ ] 创建不变的主机,而不是不断地给你长寿的服务器打补丁和升级。(参见Immutable Infrastructure Can Be More Secure).
  • [ ] 使用入侵检测系统来最大化减少 APT 攻击带来的影响。

运营

  • [ ] 关闭未使用的服务和服务器。断电的服务器是最安全的。

测试

  • [ ] 审计你的设计和实施。
  • [ ] 做渗透测试。除了你之外,还可以叫其他人进行渗透测试。

培训

  • 就关于社会工程领域中的潜在威胁和相关防护技术,要对员工(特别是高级员工)进行培训。

最后,制定一个计划

  • [ ] 做一个威胁模型,描述你正在防御对象。按主次列出可能的威胁和参与者。
  • [ ] 制定一份可实操的安全事故计划。总有一天你会需要的。

做 Web 开发必备的安全核对清单,首发于文章 – 伯乐在线