网络应用程序安全指南/不安全的 数据传输
未加密传输的数据可以被嗅探。这不仅可以为攻击者提供有价值的信息,还可以提供会话 cookie 的内容,使攻击者能够劫持会话。此外,不安全的通信可以被攻击者修改。
要防止这种类型的攻击
- 对任何和所有数据传输使用 SSL/TLS (https)
- 不要通过 http 开始通信,只在“需要”时重定向到 https
- 使用“secure”属性标记 cookie
- 尽可能使用 Strict-Transport-Security 标头
- 教育用户访问https://URL 直接
- 如果您的网络应用程序执行 HTTPS 请求,请确保它验证证书和主机名
- 如果连接到内部服务器,请考虑限制受信任的 CA
基本原理
使用 https 确保所有数据传输都已加密,并且服务器已通过身份验证。未加密页面发送的重定向可以被攻击者删除或修改。因此,从普通 http 到 https 的过渡可以被破坏,使任何在切换到 https 之前的普通 http 通信变得危险。将 cookie 标记为仅安全确保它们永远不会通过未加密的连接传输,以防止嗅探。
STS 标头确保在首次访问后,即使用户访问http://URL,请求通过安全 https 执行。这可以防止对未加密重定向的 SSLstrip 攻击。教育用户直接访问https://URL 直接为第一个请求和不支持 STS 且忽略标头的浏览器提供此保护。这种教育可以通过在端口 80 上不提供任何内容或只提供没有可点击链接的信息页面来支持,以强制用户输入正确的 URL 并消除偷懒并省略“https://”的动机。
在某些网络应用程序中,网络服务器执行 HTTPS 请求(例如,当获取或推送数据到 API 或运行 OpenID 或 OAuth 协议时)。只有当启动连接的软件(即您的网络应用程序)正确验证远程证书时,HTTPS 才是安全的。
- 检查证书是否仍然有效
- 检查证书是否由受信任的 CA 签署(需要受信任的 CA 列表)
- 检查您正在连接到的主机名是否与证书中的名称匹配(执行 SSL 处理的包装器需要访问主机名)
某些库默认情况下不会这样做,这使得 HTTPS 连接不安全!如果您不需要提供受信任的 CA 列表,或者看起来 SSL 包装器无法访问您正在连接到的主机名,请将其视为可疑。要测试此问题,请尝试连接到使用未过期自签名证书的主机,然后尝试连接到使用有效证书但使用与证书中指定的名称不同的主机名(例如,按其 IP 地址寻址主机)的主机。如果这两个连接都成功,您的库/配置就不安全。
在 PHP 中,执行 HTTP(S) 请求的两种标准方法都存在问题:如果使用低于 7.10 版本的 cURL,cURL 库默认情况下不会检查证书。Stream API 始终需要显式配置(影响所有使用 url_fopen
的函数,例如 fopen()
、file()
、file_get_contents()
)。对于 cURL,请设置 CURLOPT_SSL_VERIFYPEER
和 CURLOPT_CAINFO
。对于 Stream API,请使用带有 verify_peer
、CN_match
和 cafile
SSL 上下文选项 的流上下文。
如果您正在连接到内部服务器,请考虑将受信任的 CA 列表限制为您正在使用的 CA。这降低了来自受损/恶意 CA 的风险。默认的 CA 包通常包括您可能认为不可信的 CA,例如中国互联网主管部门 CNNIC。