Skip to content

Infinite looping requests when proxy auth creds are incorrect in Win32 #978

Closed
@trevorlacey-msft

Description

@trevorlacey-msft

Summary
If cpprestsdk is used in an environment where a web proxy requires authentication, and if invalid username/password is provided, the request will continuously be retried. (Only tested in WinHTTP.)

Details
Configure http_client with proxy credentials:

  http_client_config clientConfig;
  web::web_proxy proxy;
  web::credentials proxyCreds(U"username", U"invalidpassword");
  proxy.set_credentials(proxyCreds);
  clientConfig.set_proxy(proxy);

The initial request will result in a 407 ("Proxy Authentication Required") response error and call winhttp_client::handle_authentication_failure which will replay the request but with the proxy creds. That subsequent request will also fail because the credentials are invalid, but winhttp_client::handle_authentication_failure will continue replying the request over and over.

Why?

bool is_redirect = false;
try
{
    web::uri current_uri(get_request_url(hRequestHandle));
    is_redirect = p_request_context->m_request.absolute_uri().to_string() != current_uri.to_string();
}
catch (const std::exception&) {}

if (is_redirect || !p_request_context->m_proxy_authentication_tried)
{
    cred = p_request_context->m_http_client->client_config().proxy().credentials();
    p_request_context->m_proxy_authentication_tried = true;
}

is_redirect is always true because of a minor bug in winhttp_client::get_request_url:

DWORD urlSize{ 0 };
if(FALSE == WinHttpQueryOption(hRequestHandle, WINHTTP_OPTION_URL, nullptr, &urlSize) || urlSize == 0)
{
    return U("");
}

The WinHttpQueryOption function will always return FALSE when lpBuffer is nullptr. Before bailing out, we must first check the result GetLastError(). For example:

DWORD urlSize{ 0 };
if(FALSE == WinHttpQueryOption(hRequestHandle, WINHTTP_OPTION_URL, nullptr, &urlSize) || urlSize == 0)
{
    if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
    {
        return U("");
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions