Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTPS Connection: adding password on header - Is this safe? #665

Closed
tehort opened this issue Jun 3, 2019 · 1 comment
Closed

HTTPS Connection: adding password on header - Is this safe? #665

tehort opened this issue Jun 3, 2019 · 1 comment
Labels

Comments

@tehort
Copy link

tehort commented Jun 3, 2019

I`m setting up a new WebAPI server (ASP NET), we're using HTTPS and checking for a valid password, which is passed through the message header.

Server side, I can check if every package is delivered through HTTPS, and if it contains the correct header with password information.

My question is: We're using refit on the API client, inserting the password as a header on every package. Can the client pass the header, or a single message unencrypted?

Here`s the code:

Connection and initialization

var httpClient = new HttpClient(new AuthenticatedHttpClientHandler())
{
    BaseAddress = new Uri("https://10.103.208.16:45456/")
}; 

var nsAPI = RestService.For<Interface1>(httpClient);

Method call:

var sugars = await nsAPI.GetMakeUps(); 

HttpHandler which inserts the password

class AuthenticatedHttpClientHandler : HttpClientHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Headers.Add("pw", "MY_SECRET_PW");
        return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
    }
}

Am I at risk that the password could be sniffed unencrypted? Can I enforce refit to communicate / send packages only through HTTPS connections?

@bennor
Copy link
Contributor

bennor commented Jun 6, 2019

Refit uses the standard .NET HttpClient (you're using one explicitly in your example), so it is as secure as if you were using HttpClient directly.

In your example, you're setting the base address to an HTTPS URI and that's all Refit will ever use to initiate requests.

However, if your server redirected to a HTTP URI (which is very unlikely) and the HttpClient was configured to auto-follow redirects (which may be the default), then it is possible for a follow up request to be redirected to this insecure URL. If that were the case, your handler would be sending the password on an insecure request.

This is a fairly unlikely situation, but there's an easy fix anyway -- just check the scheme of the URL before attaching your password:

class AuthenticatedHttpClientHandler : HttpClientHandler
{
	protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
	{
		if(string.Equals(request.RequestUri.Scheme, "https", StringComparison.OrdinalIgnoreCase))
			request.Headers.Add("pw", "MY_SECRET_PW");
		return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
	}
}

That way if you somehow wind up issuing an HTTP request instead of an HTTPS one, you won't send your password with it.

If you're concerned about whether your password is sniffable in an HTTPS request, it's only really possible if the computer running the client has been compromised and is trusting someone it shouldn't. But if that's the case there are easier ways to get at your password e.g. by decompiling the DLL or reading config files, for example.

@bennor bennor closed this as completed Jun 6, 2019
@lock lock bot added the outdated label Sep 4, 2019
@lock lock bot locked and limited conversation to collaborators Sep 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants