WinHTTP Security Considerations
The following security considerations apply to applications that use WinHTTP:
- Server certificates are only verified once per session. After a certificate has been verified, it remains valid for the duration of the current session. As long as the certificate fingerprint matches, which indicates that the certificate has not changed, the certificate continues to be re-validated. As a result, any change in the validation criteria, through the protocol, revocation-check, or certificate-error-ignore flags, does not take effect once the certificate is verified. To force such a change to take effect immediately, the current session must be ended and a new one started. Similarly, expiration of a certificate during the course of a session can only be detected if the application itself checks the certificate server periodically to retrieve expiration data.
- Auto-proxy involves downloading and executing scripts. The automatic proxy discovery support involves detecting through DHCP or DNS, downloading, and executing proxy scripts such as Java scripts. To achieve a higher degree of security, an application must avoid passing the WINHTTP_AUTOPROXY_RUN_INPROCESS flag, so that the auto-proxy discovery is initiated out-of-process. Even then, WinHTTP tries by default to run an auto-proxy script in-process if the script fails to run properly out-of-process. If you believe that this fallback behavior poses an unacceptable risk, disable the fallback behavior with the WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY flag.
- WINHTTP_STATUS_CALLBACK functions must return promptly. When you write one of these callback functions, be careful that it does not block. For example, neither the callback nor any function it calls should display a user dialog or wait for an event. If a WINHTTP_STATUS_CALLBACK function does block, it affects WinHTTP's internal scheduling and causes other requests within the same process to be denied service.
- WINHTTP_STATUS_CALLBACK functions must be reentrant. When writing a callback, avoid static variables or other constructs that are unsafe under reentrance, and avoid calling other functions that are not reentrant.
- If asynchronous operation is possible, pass NULLs for OUT parameters. If you have enabled asynchronous operation by registering a callback function, always pass NULL values for such OUT parameters as lpdwDataAvailable for WinHttpQueryDataAvailable, lpdwBytesRead for WinHttpReadData, or lpdwBytesWritten for WinHttpWriteData. Under some circumstances, the calling thread is terminated before the operation completes, and if the OUT parameters are not NULL, the function can end up writing to memory that has already been freed.
- Passport authentication is not foolproof. Any cookie-based authentication scheme is vulnerable to attack. Passport version 1.4 is cookie based, and therefore subject to the vulnerabilities that are associated with any cookie or form-based authentication scheme. Passport support is disabled by default in WinHTTP; it can be enabled using WinHttpSetOption.
- Basic authentication should only be used over a secure connection. Basic authentication, which sends the user name and password in clear text (see RFC 2617), should be used only over encrypted SSL or TLS connections.
- Setting Auto-Logon Policy to "low" can pose a risk. When the Auto-Logon Policy is set to low, a user's logon credential can be used to authenticate against any site. However, it is not good security practice to authenticate against sites you do not trust.
- SSL 2.0 connections are not used unless explicitly enabled. The TLS 1.0 and SSL 3.0 security protocols are considered more secure than SSL 2.0. By default, WinHTTP requests TLS 1.0 or SSL 3.0 when negotiating an SSL connection, not SSL 2.0. SSL 2.0 support in WinHTTP can only be enabled by calling WinHttpSetOption.
- Certificate-revocation checking must be explicitly requested. By default, when performing certificate authentication, WinHTTP does not check whether the server's certificate has been revoked. Certificate-revocation checking can be enabled using WinHttpSetOption.
- Applications must ensure that a session maps to a single identity. A WinHTTP session should map to one and only one identity; that is, a WinHTTP session is used to manage the Internet activity of a single authenticated user, or a group of anonymous users. However, because WinHTTP does not enforce this mapping automatically, your application must take steps to ensure that only a single identity is involved.
- Operations on a WinHTTP request handle should be synchronized. For example, an application should avoid closing a request handle on one thread while another thread is sending or receiving a request. To terminate an asynchronous request, close the request handle during a callback notification. To terminate a synchronous request, close the handle when the previous WinHTTP call returns.
- Trace files contain sensitive information. Trace files are protected using Access-Control Lists (ACLs) so that one can normally be accessed only by the local administrator or by the user account that created it.Avoid compromising trace files by any unauthorized access.
- Avoid passing sensitive data through WinHttpSetOption. Do not supply a user name, password or any other credentials to WinHttpSetOption because you have no control over the authentication scheme that is used, and the sensitive data could unexpectedly be sent in clear text. Use WinHttpQueryAuthSchemes and WinHttpSetCredentials instead of WinHttpSetOption for setting credentials.
- Automatic redirection can pose a security risk. By default, redirection (a 302 message) is followed automatically even for a POST. To avoid the possibility of spurious redirects, applications should disable auto-redirect or monitor re-direction in callbacks when posting sensitive information.
- User-defined headers are transferred across redirects unchanged. User-defined headers, such as cookies added with WinHTTPAddRequestHeaders, are transferred across redirects without modification, while headers generated by WinHTTP are automatically updated. If transferring a user-defined header across redirects poses a security risk, use the WINHTTP_STATUS_CALLBACK callback with the WINHTTP_CALLBACK_STATUS_REDIRECT completion to modify the header in question whenever a redirect occurs.
- WinHTTP is not reentrant in synchronous mode. Because WinHTTP is not reentrant in synchronous mode, do not schedule asynchronous procedure calls (APC) that can call into WinHTTP on an application thread that executes inside a WinHTTP function. While in synchronous mode, WinHTTP performs an "alertable wait," and if the waiting thread is pre-empted to execute an APC and then later re-enters WinHTTP again, WinHTTP's internal state can be corrupted.