WinHTTP 安全注意事项
下列安全注意事项适用于使用 WinHTTP 的应用程序:
- 每个会话仅验证一次服务器证书。 验证证书后,该证书在当前会话的持续时间内仍然有效。 只要证书指纹匹配,表明证书尚未更改,证书将继续被重新验证。 因此,通过协议、吊销检查或证书错误忽略标志对验证标准的任何更改,在证书通过后都不会生效。 若要强制此类更改立即生效,必须结束当前会话并启动一个新会话。 同样,只有在应用程序本身定期检查证书服务器以检索过期数据时,才能检测到会话过程中的证书过期。
- 自动代理涉及下载和执行脚本。 自动代理发现支持涉及通过 DHCP 或 DNS 检测、下载和执行代理脚本(如 Java 脚本)。 为了获得更高的安全性,应用程序必须避免传递 WINHTTP_AUTOPROXY_RUN_INPROCESS 标志,以便自动代理发现在进程外启动。 即便如此,如果脚本无法在进程外正常运行,WinHTTP 会默认尝试在进程内运行自动代理脚本。 如果您认为这种回退行为构成不可接受的风险,请使用 WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY 标志禁用回退行为。
- WINHTTP_STATUS_CALLBACK 函数必须及时返回。 编写其中一个回调函数时,请注意不要阻塞。 例如,回调及其调用的任何函数都不应显示用户对话框或等待事件。 如果 WINHTTP_STATUS_CALLBACK 函数确实阻止,它将影响 WinHTTP 的内部计划,并导致同一进程中的其他请求被拒绝服务。
- WINHTTP_STATUS_CALLBACK 函数必须是可重入的。 编写回调时,请避免使用在重入时不安全的静态变量或其他构造,并避免调用非重入的其他函数。
- 如果可以执行异步操作,请传递 OUT 参数的 NUL。 如果通过注册回调函数启用了异步操作,请始终为 WinHttpQueryDataAvailable 的 lpdwDataAvailable、WinHttpReadData 的 lpdwBytesRead 或 WinHttpWriteData 的 lpdwBytesWritten 等 OUT 参数传递 NULL 值。 在某些情况下,调用线程在操作完成之前终止,如果 OUT 参数不为 NULL,函数最终可以写入已释放的内存。
- 护照身份验证并非万无一失。 任何基于 Cookie 的身份验证方案都容易受到攻击。 Passport 版本 1.4 基于 Cookie,因此会受到与任何 Cookie 或基于表单的身份验证方案关联的漏洞的约束。 默认情况下,WinHTTP 中禁用 Passport 支持;可以使用 WinHttpSetOption 启用它。
- 基本身份验证只能通过安全连接使用。 基本身份验证以明文形式发送用户名和密码,(请参阅 RFC 2617),应仅通过加密的 SSL 或 TLS 连接使用。
- 将自动登录策略设置为“低”可能会带来风险。 当自动登录策略设置为低时,用户的登录凭据可用于对任何站点进行身份验证。 但是,针对不信任的站点进行身份验证不是很好的安全做法。
- 除非明确启用,否则不会使用 SSL 2.0 连接。 TLS 1.0 和 SSL 3.0 安全协议被认为比 SSL 2.0 更安全。 默认情况下,WinHTTP 在协商 SSL 连接时请求 TLS 1.0 或 SSL 3.0,而不是 SSL 2.0。 WinHTTP 中的 SSL 2.0 支持只能通过调用 WinHttpSetOption 来启用。
- 必须明确要求证书吊销检查。 默认情况下,执行证书身份验证时,WinHTTP 不会检查服务器的证书是否已吊销。 可以使用 WinHttpSetOption 启用证书吊销检查。
- 应用程序必须确保会话映射到单个标识。 WinHTTP 会话应映射到一个且仅一个标识;也就是说,WinHTTP 会话用于管理单个经过身份验证的用户或一组匿名用户的 Internet 活动。 但是,由于 WinHTTP 不会自动强制实施此映射,因此应用程序必须采取措施以确保只涉及单个标识。
- 应同步 WinHTTP 请求句柄上的操作。 例如,应用程序应避免在一个线程上关闭请求句柄,而另一个线程正在发送或接收请求。 若要终止异步请求,请在回调通知期间关闭请求句柄。 若要终止同步请求,请在上一个 WinHTTP 调用返回时关闭句柄。
- 跟踪文件包含敏感信息。 跟踪文件使用访问控制列表 (ACL) 进行保护,以便通常只能由本地管理员或创建它的用户帐户访问。避免任何未经授权的访问破坏跟踪文件。
- 避免通过 WinHttpSetOption 传递敏感数据。 不要向 WinHttpSetOption 提供用户名、密码或任何其他凭据,因为您无法控制所使用的身份验证方案,并且敏感数据可能会意外地以明文形式发送。 使用 WinHttpQueryAuthSchemes 和 WinHttpSetCredentials 而不是 WinHttpSetOption 设置凭据。
- 自动重定向可能会带来安全风险。 默认情况下,即使对于 POST,重定向(302 消息)也会自动遵循。 为了避免出现虚假重定向的可能性,应用程序应在发布敏感信息时禁用自动重定向或监视回调中的重定向。
- 用户定义的标头在未更改的重定向之间传输。 用户定义的标头(如使用 WinHTTPAddRequestHeaders 添加的 Cookie)在不修改的情况下跨重定向传输,而 WinHTTP 生成的标头将自动更新。 如果跨重定向传输用户定义的标头会带来安全风险,请使用具有 WINHTTP_CALLBACK_STATUS_REDIRECT 完成的 WINHTTP_STATUS_CALLBACK 回调,在发生重定向时修改有问题的标头。
- WinHTTP 在同步模式下不重入。 由于 WinHTTP 不在同步模式下重入,因此不要计划可以在 WinHTTP 函数内执行的应用程序线程上调用 WinHTTP 的异步过程调用 (APC)。 在同步模式下,WinHTTP 执行“可警报等待”,如果等待线程已抢占执行 APC,然后再次重入 WinHTTP,则 WinHTTP 的内部状态可能会损坏。