====== Web 开发者安全自检列表 ======
* 原文:[[https://simplesecurity.sensedeep.com/web-developer-security-checklist-f2e4f43c9c56|Web Developer Security Checklist]]
===== 自检列表 =====
==== 数据库 ====
* 涉及用户的敏感数据(口令、邮箱、信用卡号等),需要尽可能加密(会限制获取与精确匹配查找功能);
* 如果你的数据库支持空闲低耗加密功能(比如 AWS Aurora),那么就启用它以确保存储于硬盘的数据是加密的,包括备份。
* 使用最小权限账号来操作数据库,禁止直接使用 root 账号,清理无用账号及弱密码账号。
* 存储与分发 secret 要使用专门的数据库,不要在程序里硬编码
* 杜绝 SQL 注入攻击,就只使用 SQL 预处理语句(SQL prepared statements)。 比如使用 npm 的 [[https://www.npmjs.com/package/mysql2|mysql2]] 库,而不是 ''mysql'' 库, 因为前者支持预处理。
==== 开发 ====
* 确保你产品所用的操作系统、库、组件、代码的相应版本都经过安全扫描。这步骤最好加入你的自动持续集成/持续分发系统。(得包括开发工具)
* 开发环境与部署环境的安全要求应该等同,确保在安全隔离的开发环境下开发软件。
==== 身份认证 ====
* 确保所有密码经过合适算法哈希,比如[[wp>Bcrypt|Bcrypt]]。不要记录哈希所用数,哈希所用数要随机生成。
* 登录、遗忘密码、重置密码等业务逻辑要使用已被证明的最佳实践方案。不要自己造个新的——想要在所有场景下都能不出问题是很难的。
* 实现简单但足够的规则来促使用户使用足够长足够随机的密码。
* 在所有服务上都使用 MFA ([[wp>Multi-factor_authentication|Multi-Factor Authentication]] 来提供登陆
==== 对付拒绝服务攻击 ====
* 确保对API的DDOS攻击不会波及整个站点。最低限度为你的高耗API或者认证相关API必须有访问频次限制。可考虑在前端加验证码来帮助后端应对DDOS攻击。
* 增强用户在请求与上传数据时的长度限制与结构限制
* 可考虑使用全局缓冲代理服务(比如 [[https://www.cloudflare.com/|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 [[http://chadfowler.com/2013/06/23/immutable-deployments.html|immutable hosts]] instead of long-lived servers that you patch and upgrade. (See [[https://simplesecurity.sensedeep.com/immutable-infrastructure-can-be-dramatically-more-secure-238f297eca49|Immutable Infrastructure Can Be More Secure]]).
* Use an [[https://en.wikipedia.org/wiki/Intrusion_detection_system|Intrusion Detection System]] to minimize [[https://en.wikipedia.org/wiki/Advanced_persistent_threat|APTs]].
==== 运维 ====
* 关闭不在用的服务与服务器;最安全的服务是没启用的服务。
==== 测试 ====
* 审查你的设计与实现
* 做渗透测试——自己做,同时也让第三方来做渗透测试
==== 培训 ====
* 培训所有人(尤其高层人员)关于社会工程学的危险性以及相关的安全工具。
==== 最后,要有预案 ====
* 要有一个威胁模式来描述你的防卫针对的对象,它得列出各类危险行为并排列优先级。
* 要有一个实践性的安全事件预案,未来某一天总会用到。