So I was looking at an example of how to implement public key pinning for when your app connects to your web service and you want to have your app ensure it's really talking to your server.
http://blogs.windows.com/buildingapps/2015/10/13/create-more-secure-apps-with-less-effort-10-by-10/
They do a test HTTPS request and then check the thumbprint of the certificate:
private async Task DemoSSLRoot()
{
// Send a get request to Bing
HttpClient client = new HttpClient();
Uri bingUri = new Uri("https://www.bing.com");
HttpResponseMessage response = await client.GetAsync(bingUri);
// Get the list of certificates that were used to validate the server's identity
IReadOnlyList<Certificate> serverCertificates = response.RequestMessage.TransportInformation.ServerIntermediateCertificates;
// Perform validation
if (!ValidCertificates(serverCertificates))
{
// Close connection as chain is not valid
return;
}
PrintResults("Validation passed\n");
// Validation passed, continue with connection to service
}
private bool ValidCertificates(IReadOnlyList<Certificate> certs)
{
// In this example, we iterate through the certificates and check that the chain contains
// one specific certificate we are expecting
for(int i=0; i<certs.Count; i++)
{
PrintResults("Cert# " + i + ": " + certs[i].Subject + "\n");
byte[] thumbprint = certs[i].GetHashValue();
// Check if the thumbprint matches whatever you are expecting
// d4 de 20 d0 5e 66 fc 53 fe 1a 50 88 2c 78 db 28 52 ca e4 74
byte[] expected = new byte[] { 212, 222, 32, 208, 94, 102, 252, 83, 254, 26, 80, 136, 44, 120, 219, 40, 82, 202, 228, 116 };
if (ThumbprintMatches(thumbprint, expected))
{
return true;
}
}
return false;
}
Now my question is: With this approach, couldn't an attacker selectively allow your app to authenticate the first time to your web server and establish that it's trusted, and then immediately switch over to their malicious HTTPS server? It seems so, since only the initial "Hello World" request is validated...