1

I want to allow users of our website to restrict access to their account from devices they have explicitly authorized. This will be checked at the connection and each time the IP address changes.

To do this, I need to identify the device and I must avoid another device being able to pass for an authorized device.

I could, for example, save a UUID in a secure cookie (flags: httpOnly + secure) that the server (in HTTPS + HSTS) could check. However, via an MITM proxy, the attacker could potentially discover the token and use it as many times as he wants on several machines and even when the user is no longer connected to the infected proxy.

I think it is possible to reduce the risks by coupling this technique with a web push API call. This requires of course a browser that supports it (~ 80%) and the user agrees to receive our notifications. The idea would be that the server receiving the UUID of the cookie, sends a push notification containing a random token to the device, then the device forward the token to the server to prove that it is indeed the authorized device .

This method does not solve MITM proxy attacks, but once the person is no longer behind this infected network, the attacker can no longer spoof the device identify.

Push notifications are encrypted, but I can also encrypt[EDIT: obfuscate] the sent random token by a simple XOR operation with the UUID value of the cookie as the key.

Do you have more safest way to identify a device without requiring human action please?

[EDIT: I precise, the subscription to push notification is done only one time, and could be requested to be done from a secure network, like at home, to prevent MITM proxy while the subscription.]

lakano
  • 155
  • 8
  • If an attacker is able to MITM your HTTPS connection then no method is going to be secure, whatever identifier you use the attacker can just copy and spoof/replay. But you cannot MITM HTTPS without compromising the end-users device to install a malicious root CA certificate, and if the device is compromised you have lost anyway. Why is this something you are worried about? – Sean Burton Oct 06 '17 at 16:26
  • I known this not solve the moment where the user is connected to an MITM proxy. But this solve him when he's no more connected to the infected network, because the attacker couldn't spoof anymore the identity of the device. – lakano Oct 06 '17 at 17:00
  • I realize this sounds like a nitpick, but to be clear what you have a misnomer here: "I can also **encrypt** the sent random token by a simple XOR operation with the UUID value of the cookie as the key." What you propose isn't encryption but simple obfuscation. Very big (and important) difference. – Conor Mancone Oct 06 '17 at 17:59
  • @ConorMancone Sorry for my english, it's not always easy to use the good words. – lakano Oct 06 '17 at 18:05

2 Answers2

1

I'm not sure if your suggestion of push notification is really going to help. For that to work the client still has to "subscribe" itself to the push notifications. What would stop a MITM from intercepting the end-client's request to subscribe to push notifications and subscribe itself instead?

The internet is inherently built around the concept of "anonymous" clients initializing conversations with servers. It is possible for a client to uniquely identify a server via SSL certificate validation, but nothing about the internet is really designed to do the opposite.

What it really boils down to is that if doing what you wanted to do was easy and fool-proof, then every server everywhere would do it and stolen credentials would be a thing of the past. That obviously isn't the case though.

Conor Mancone
  • 29,899
  • 13
  • 91
  • 96
  • Hi Conor, thanks for your answer. Before user subscribe to push notification, we could ask him to be connected to a safe network. Web Push API is recent and not yet supported by all browsers, this surely explain why others experts don't yet use it like my suggestion. But if you have a safest way to suggest, I'm open :) – lakano Oct 06 '17 at 16:50
  • Regarding doing the opposite, you can use TLS client auth, but that requires setting up a key and certificate for the user so can't work without human action – Sean Burton Oct 06 '17 at 17:08
  • @SeanBurton It's a good idea yes, this could be done when the user tell us which device need to be authorized. But, is the TLS cert could be intercepted by a MITM proxy and used later by the attacker ? – lakano Oct 06 '17 at 17:26
  • @lakano This may be helpful for you: https://security.stackexchange.com/questions/23880/why-a-client-authentication-is-not-commonly-performed-in-the-tls-protocol What you are asking isn't strictly impossible, but I don't think it is as easy as you think, nor do I think your push notifications system is really going to get the job done. This service may be of interest to you: https://blog.cloudflare.com/introducing-tls-client-auth/ – Conor Mancone Oct 06 '17 at 17:36
  • @ConorMancone Thanks for the links, yep I've already read the CloudFlare article about it. But I don't known if TLS cert as suggested by Sean could be safer than push notification. If the TLS cert could be intercepted by the MITM proxy and re-used later, then push notification are safer. – lakano Oct 06 '17 at 17:45
  • 1
    @lakano To be frank, I don't think it is possible for your off-the-cuff client-authentication method to be more secure (or even as-secure) as actual client authentication designed by the experts. Not to say that we should defer to experts because they are experts, but when it comes to security and encryption it is *very* easy to get things wrong. Again, reiterating my question: if someone is vulnerable to MITM what will stop the MITM from intercepting your push notification-subscription request and subscribing themselves instead of the client? I don't think your plan is any more secure. – Conor Mancone Oct 06 '17 at 17:58
  • As said before, we could ask them to subscribe ONLY if they are connected to a safe network. So, later, if they are inside a public WiFi network with a MITM proxy, the attacker could read the push notification and spoof this identify of the device while the user is connected, but can't continue later, because the attacker doesn't have the future token sent by push notification. This is why I think it's a safer than TLS Cert auth. – lakano Oct 06 '17 at 18:10
  • 1
    @lakano What makes you think that a user knows whether or not they are connected to a safe network? You can't even trust a user to select a secure password, and there are plenty of MITM attacks that leave the victim completely unaware. For that matter, you would be better off asking them to connect to a "secure" network in order to complete the client-side SSL exchange via something like cloudflare. – Conor Mancone Oct 06 '17 at 18:17
  • Of course, they can't be sure it's a safe/secure network. But we can tell them to do this subscription from home and not from a public Wi-Fi. The push notification subscription is only required one time. This means, if the subscription is done without sniffing, then later, if the user go inside a public Wi-Fi with a MITM proxy, the attacker can spoof the device while the user is connected, but can't re-connect after because he need the token sent by push. For TLS Auth, the cert is sent every time, so when it's intercepted, the attacker can spoof the device later on many device he want. – lakano Oct 06 '17 at 18:41
  • @lakano: TLS client-auth cannot be 'spoofed' with the cert, only with the privatekey, which cannot be intercepted because it is not sent. – dave_thompson_085 Oct 07 '17 at 01:00
  • @dave_thompson_085 Could you please create a new answer where you explain me why this can't be intercepted? mitmproxy said: SSL/TLS certificates for interception are generated on the fly. Eg: SSLv3 should protect us because requiring to send all previous handshakes that the client->proxy fake cert can't be guess... but SSLv3 have been hacked. And if you can confirm me this dont need human action (excepted when the user register his device). So, our server need to generate it automatically, the user install it, and that's all. Each time the IP address change we need to check the cert silently. – lakano Oct 07 '17 at 09:08
  • @lakano: SSL/TLS interceptor like mitmproxy is concerned with faking the servers, not the clients (and even for the server the client _can_ detect the fakery but is configured to accept it, sometimes legitimately and sometimes by trickery). It cannot fake a client to a server. (Unless of course you give it a legit cert-and-key, but then it's not faking.) If you use client-cert it is checked by the SSL/TLS stack on every connection regardless of IP (unless you use resumption, but that's cryptographically bound to the full handshake that did check and anyway it's optional). ... – dave_thompson_085 Oct 08 '17 at 00:17
  • ... Yes you should no longer use SSLv3, for anything, but the problem with SSLv3 is in the symmetric encryption (namely POODLE) and has nothing to do with authentication of either server or client. – dave_thompson_085 Oct 08 '17 at 00:18
  • @dave_thompson_085 Ok, thanks for the confirmation. I just need to known if this don't require human intervention. – lakano Oct 08 '17 at 13:32
  • @dave_thompson_085 After some search, I found cfssl to generate TLS certs, but there is not a good way to permit user to install the cert easily. I can force to download it on Firefox and this will propose to install the cert, but all others browsers only download the cert file, and they need to make a lots of complex steps to install it. Also, in my case, on React Native, I can't download it and install it automatically. So this require human actions, and as explained in the subject/question, I need to found a way without human action (or an easy action at registration process). – lakano Oct 10 '17 at 09:42
0

I answer to myself after some research.

Client TLS certificate can't be used while browsers will not permit to easily import the certificate. Currently, most browsers require complex human actions: download the cert file, go in settings, advanced, certificats management, import, select the file to import. It's a very bad experience for the user, we can't ask the user to do this after sign up on our website.

But, we can have something similar, with Web Crypto API (all functions aren't fully supported by all browsers, that require polyfill). We generate asymetric keys public/private when the user request the autorisation of the device.

Then, in the server-side, we can save the public key of the device and the associated hash (SHA256) of the public key as a « deviceID ». Each time the user make a request to the API, we add in the header the deviceID and a proof with a signature, the request hash signed by the private key of the device (we will add a nonce to prevent replay attack).

In the client-side, the keys are saved encrypted by the user password inside IndexedDB. Of course, if the user clear the indexedDB data of the site, the autorisation for this device is lost.

lakano
  • 155
  • 8
  • This is only mildly more secure than a standard session token. If the private key is stolen then a malicious actor can act as the authorized device and your system won't know the difference. The only reason this is even slightly more secure than normal device authentication is because you don't have to transmit the private key, which gives less points for failure. However, in the event of an XSS attack (which is one of the most relevant security concerns), your device authentication is completely vulnerable. This just makes you think you are more secure while giving you more code to manage. – Conor Mancone Jan 29 '18 at 18:56