As the topic is a bit vague I have decided to ask you guys here what do you think and what is the best practice in given scenario.
Disclaimer: I am programmer, and although I know a bit about security I don't posses an in-depth knowledge of attack, security and exploit methods and opportunities in given scenario.
I am working on connecting our system with the external system that is going to consume and process some of data we are sending to them.
Potential problem that I see is in Auth part of making request.
They want us to create GET request on their Api endpoint. It is secure (HTTPS) endpoint, and username and password are to be sent in body of request (application/x-www-form-urlencoded
).
In return we are to get back token for further authentication.
I know that sending Username and Password in Get method type would be security nightmare as URL's persist in browsers history.
I have read about similar situation HERE and HERE talking about security through obscurity but I am not sure if it applies here.
Why I don't think this is security issue:
- We are not authenticating using browser, rather HttpClient
- Data is sent in body of request
- Endpoint is using secure protocol (HTTPS)
What do you think ? Is this wrong approach and/or potential security risk ?
Update: As @stefen pointed out that: RFC 7231 4.3.1:
"A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request."
I will leave example implementation of given call.
My HttpWrapper.cs:
public static class HttpClientWrapper<T> where T : class
{
public static async Task<T> GetUrlEncoded(HttpClient httpClient, string url, Dictionary<string, string> parameters)
{
T result = null;
var request = new HttpRequestMessage(HttpMethod.Get, url) { Content = new FormUrlEncodedContent(parameters) };
var response = await httpClient.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
await response.Content.ReadAsStringAsync().ContinueWith((Task<string> x) =>
{
if (x.IsFaulted)
throw x.Exception;
result = JsonConvert.DeserializeObject<T>(x.Result);
});
return result;
}
}
Usage of Http wrapper and Http call as so:
Dictionary<string, string> urlParams = new Dictionary<string, string>();
urlParams.Add("username", "Username");
urlParams.Add("password", "Password");
urlParams.Add("grant_type", "password");
AuthResultViewModel outcome = await HttpClientWrapper<AuthResultViewModel>.GetUrlEncoded(httpClient, "https://some-endpoint.com/token", urlParams);
This works, and I get token.
Cache-Control
though it depends on the client use whether it works.Make a GET request to this endpoint: https://some-endpoint.com with Body type = application/x-www-form-urlencoded
And the following values in the body: grant_type = password username = #yourUsername password = #yourPassword
I will post working example in C# of Get method in body which works and fetches token just fine.