Web 开发者安全自检列表
自检列表
数据库
- 涉及用户的敏感数据(口令、邮箱、信用卡号等),需要尽可能加密(会限制获取与精确匹配查找功能);
- 如果你的数据库支持空闲低耗加密功能(比如 AWS Aurora),那么就启用它以确保存储于硬盘的数据是加密的,包括备份。
- 使用最小权限账号来操作数据库,禁止直接使用 root 账号,清理无用账号及弱密码账号。
- 存储与分发 secret 要使用专门的数据库,不要在程序里硬编码
- 杜绝 SQL 注入攻击,就只使用 SQL 预处理语句(SQL prepared statements)。 比如使用 npm 的 mysql2 库,而不是
mysql
库, 因为前者支持预处理。
开发
- 确保你产品所用的操作系统、库、组件、代码的相应版本都经过安全扫描。这步骤最好加入你的自动持续集成/持续分发系统。(得包括开发工具)
- 开发环境与部署环境的安全要求应该等同,确保在安全隔离的开发环境下开发软件。
身份认证
- 确保所有密码经过合适算法哈希,比如Bcrypt。不要记录哈希所用数,哈希所用数要随机生成。
- 登录、遗忘密码、重置密码等业务逻辑要使用已被证明的最佳实践方案。不要自己造个新的——想要在所有场景下都能不出问题是很难的。
- 实现简单但足够的规则来促使用户使用足够长足够随机的密码。
- 在所有服务上都使用 MFA (Multi-Factor Authentication 来提供登陆
对付拒绝服务攻击
- 确保对API的DDOS攻击不会波及整个站点。最低限度为你的高耗API或者认证相关API必须有访问频次限制。可考虑在前端加验证码来帮助后端应对DDOS攻击。
- 增强用户在请求与上传数据时的长度限制与结构限制
- 可考虑使用全局缓冲代理服务(比如 CloudFlare来减轻DDOS攻击。
网络传输
- 全站都使用 TLS, 不要只在登录页面使用。 传统上,使用
strict-transport-security
头来强制所有请求使用HTTPS。 - Cookies 必须
httpOnly
、安全的、并区分于路径域名。 - 使用内容安全策略(CSP)禁止所有 unsafe-* backdoors. 配置起来虽然很麻烦但很值得做。 对 CDN 内容实用 CSP Subresource Integrity.
- 在答复客户端时使用
X-Frame-Option
,X-XSS-Protection
头。 - 使用 HSTS 回复来强制仅 TLS 访问。在服务端重定向所有 HTTP 请求到 HTTPS。
- 在所有 form 表单中使用
CSRF tokens
。在新浏览器上,使用新的SemaSite Cookie
回复头,可根治跨站攻击。
API接口
- 确保资源不会在你的公开接口中被枚举。(API 里指定资源个体要用 uuid 而不是顺序的 id)
- 确保接口使用者经过充分的认证与授权
- 在 API 中使用“金丝雀”检查法来区别非法与反常的攻击性请求。
注释:矿井中的金丝雀 17世纪,英国矿井工人发现,金丝雀对瓦斯这种气体十分敏感。空气中哪怕有极其微量的瓦斯, 金丝雀也会停止歌唱;而当瓦斯含量超过一定限度时,虽然鲁钝的人类毫无察觉,金丝雀却早已毒发身亡。 当时在采矿设备相对简陋的条件下,工人们每次下井都会带上一只金丝雀作为“瓦斯检测指标”, 以便在危险状况下紧急撤离
数据验证与加密
- 在客户端做输入验证以让用户迅速获得反馈,但别信任客户端验证。在显示前要始终验证并加密用户的输入内容。
- 在服务端使用白名单机制来验证用户输入的每个字节。绝不直接使用用户输入内容来回复。绝不在sql语句或其它服务端逻辑中使用不受信任的用户输入。
云配置
- 确保所有服务使用最少量的端口。虽然 Security Through Obscurity 并无保护作用,但使用非标准的端口会让攻击者的攻击难度提高点。=
- 确保后台(或私有网络)的数据库与服务在公网中不可见。配置 AWS 安全组与私有网络(VPC)时要十分注意,否则会不经意让服务公开。
- 分割服务逻辑单元到私有网络中,匹配私有网络来提供服务间通讯。
- 确保所有服务只从最小集合IP地址接受数据。
- Restrict outgoing IP and port traffic to minimize APTs and “botification”.
- Always use AWS IAM roles and not root credentials.
- Use minimal access privilege for all ops and developer staff.
- Regularly rotate passwords and access keys according to a schedule.
基础设施(Infrastructure)
- Ensure you can do upgrades without downtime. Ensure you can quickly update software in a fully automated manner.
- Create all infrastructure using a tool such as Terraform, and not via the cloud console. Infrastructure should be defined as “code” and be able to be recreated at the push of a button. Have zero tolerance for any resource created in the cloud by hand — Terraform can then audit your configuration.
- Use centralized logging for all services. You should never need SSH to access or retrieve logs
- Don’t SSH into services except for one-off diagnosis. Using SSH regularly, typically means you have not automated an important task.
- Don’t keep port 22 open on any AWS service groups on a permanent basis. If you must use SSH, only use public key authentication and not passwords.
- Create immutable hosts instead of long-lived servers that you patch and upgrade. (See Immutable Infrastructure Can Be More Secure).
- Use an Intrusion Detection System to minimize APTs.
运维
- 关闭不在用的服务与服务器;最安全的服务是没启用的服务。
测试
- 审查你的设计与实现
- 做渗透测试——自己做,同时也让第三方来做渗透测试
培训
- 培训所有人(尤其高层人员)关于社会工程学的危险性以及相关的安全工具。
最后,要有预案
- 要有一个威胁模式来描述你的防卫针对的对象,它得列出各类危险行为并排列优先级。
- 要有一个实践性的安全事件预案,未来某一天总会用到。