3

TL;DR Would a potential attacker need to have my Wi-Fi password and be connected to my network in order to read HTTP requests?

Over the past year or so, I have made a few DIY home automation projects. Included in this is a garage door opener. The basic premise of which is that when I want to open the garage, the home automation hub sends an http (not https) GET request (e.g. 192.168.1.xxx/openGarage) to the DIY IoT device which then opens the garage. (The IoT device will trigger the garage whenever it receives that specific /openGarage request)

However, for some time now, this has worried me. I was wondering whether an attacker who was not connected to the network would be able to intercept the HTTP get request (192.168.1.xxx/openGarage) and then be able to replay this get request in order to open the garage without my knowing.

So, my question is: would an attacker need to be connected to my home network in order to intercept this GET request (/openGarage) or would they need to bee connected in order to see this?

Thank you in advance for your help,

Kind regards, Rocco

P.S. I understand that making this request an https one instead would obfuscate the request, however, it is quite hard to implement proper SSL encryption on an ESP8266 which is what I am using for this IoT device. Thus, I am willing to hinge my security on the strength of my WPA2 password. That is, if an attacker would need to be connected to my network in the first place to intercept the request as per the above question.

7

Yes. An attacker would need to be on your network - either wirelessly or wired - to intercept an intra-network HTTP request. If it left your network for the broader Internet, the attacker could potentially intercept it anywhere between your property and the server, but with the server on the same local network the traffic won't leave your router. As WPA provides both encryption and replay protection, an attacker wouldn't know what message you are sending, nor would they be able to replay it (although traffic analysis - such as noting the packet size, and/or noting that a message for a particular MAC address is always sent before the garage door opens - would be possible).

However, by implementing your system this way, you're opening yourself up to the massive world of web application / web service security vulnerabilities. As a trivial example, you service right now is almost certainly vulnerable to CSRF; if any machine on your network visits a web page with 256 invisible image tags on it - one each from <img src="http://192.168.1.0/openGarage"> to <img src="http://192.168.1.255/openGarage"> - your garage door would open. JS could be used to iterate through even much larger spaces very quickly.

  • Thank you for your answer! I'm glad to hear that an attacker would need to actually be on my network to read or replay these HTTP requests. However, as you say, I do agree that this current implementation is in no way secure. I hadn't even considered the trivial attack you mentioned. Luckily, as a first line of defence, the /openGarage is just for demonstration and in reality the string is random generated. However, I appreciate that it is still rather insecure. What would you recommend is the best step forward? Looking into https? Basic http authentication? Thanks once again! – Rocco Mar 15 at 23:36
  • Basic auth wont do anything to defend in a HTTP environment. Your only hope (if HTTPS truly cant be done) is to validate the client using either a pre-shared-key or a challenge. While this would also fix the CSRF CBHacking mentioned, i think the argument of CSRF, though technically correct, is tenuous, as it insinuates someone has already figured out the /openGarage request on the network. Which would likely mean that have some level of access to your network anyway and could therefore make the request themself (that or they have read this question). – hiburn8 Mar 15 at 23:44
  • Neither of those approaches would fix the problem, as CSRF is entirely independent of HTTPS (or its lack) and basic auth is sent automatically by any browser that has logged into the site in question. Moving from GET to POST would make things marginally trickier but is no real fix either. Using some other HTTP verb would be much more secure, but specifically because browsers would refuse to send the request absent specific situations. I suggest an access token in a POST message body; a browser will happily send that but an attacker won't know the token to send. – CBHacking Mar 15 at 23:50
  • 1
    @hiburn8 I will try to look further into HTTPS as I feel it will fix many unforeseen problems. Luckily, as I stated, /openGarage specifically is just an example, in reality the string is something random (e.g. /gnexewjow) so I hope this also adds some 'security'. However, as I said in my main question, I am willing to hinge some of my security simply on the exclusivity of my network and therefore on my WPA2 passcode. – Rocco Mar 15 at 23:51
  • @CBHacking Ah I see. What do you mean by "Using some other HTTP verb"? Also how do you suggest an access token would solve the problem? Would you be able to link to a more detailed explanation of the implementation? Thanks once again – Rocco Mar 15 at 23:55
2

Unless you want to read around the subject areas involved, this is a simple question with a simple answer. YES, an attacker would need to be connected to your network (given that it is an encrypted network) in order to see the contents of packets and therefor the /openGarage API.

If thats all you care about, we're done. But I will go on to say that even in a non secured (http) environment, it might still be possible to get some level of assurance that no-one is successfully hitting up your API. The way i would do this is have a pre-shared key between the IOT device and server, which are used to generate continuously changing tokens for use to validate each-other. Essentially the same model as a one-time passcode. This seems like something even very basic IoT devices which might struggle to process HTTPS data should be able to achieve. The ideal scenario would be that the 'server' is aware of the last used token, to prevent an attacker from abusing the race-condition to re-use a token.

Pretty much any other attempt to add security would have to rely on obscurity. As a really awful example, you could change '/openGarage' to '/questions' and on that network use a DNS server such that requests appear to be going to 'stackexchange.com/questions'. Depending on what the attacker sees, they might be fooled into thinking the endpoint is of no interest/value.

Lastly. If the IoT device can handle it... some logging never hurts.

  • Apologies for repeating some of what CBHacking wrote, i think we were both typing at the same time. The CSRF he mentioned is remediated by the concept of a one-time passcode however... as i mentioned you could use. – hiburn8 Mar 15 at 23:39
  • Thank you for your detailed answer. Would you be able to go into more depth about using a pre-shared key? If it is possible, would you be able to link to a demonstration if such an implementation do I can look into seeing whether it is something I could implement into the ESP8266? – Rocco Mar 15 at 23:48
  • Based on your hardware limitations, i would imagine the best tradeoff for security and effort (given that you are not protecting the crown jewels but still want to have some assurance) would be to use the current time of the devices to encrypt a string/passphrase. The 'server' would perform this operation once at timed intervals (say per minute) and therefore the client would be able to generate a valid token within this timeframe assuming it's system clock is in reasonably good sync with the server. – hiburn8 Mar 15 at 23:54
  • So i think to make that happen all you really need to do is A) make sure that the clocks/times are in sync for the client and server. B) figure out which forms of encryption are possible on your IoT device. Given that you are only performing encrypt actions every minute and decrypt actions on every request, this shouldnt be a huge performance requirement at all. – hiburn8 Mar 15 at 23:56
  • Don't use time, it is unreliable. The best you can do is having Client and Server sharing a secret, then each request packet is signed with HMAC for authenticity and the secret is used for validation. This means that 1) you have to securely upload the same secret both to Client and Server using another medium 2) all data is publicly visible so you can't send sensitive information 3) you cannot use that public connection to update the secret on Client and Server, so you will have to updated it from time to time using a secure medium. 4)both Client and Server are vulnerable to Replay attacks – GameDeveloper Mar 16 at 7:15

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.