HTTP(S) and Websockets Security
There are a lot of open source home automation attempts out there. Many are missing some essential security that leaves them vulnerable. Those that actually allow the user to control physical things in their home are especially vulnerable. An attacker could gain control and cause an appliance to turn on-off repeatedly causing a hazard, could gain access to the home by opening a garage or door, or could just watch for human activity for other evil purposes.
I knew that getting ahead of the crowd meant imposing some strict requirements including physical and virtual security to restrict access only to those authorized and minimize the chance of an attack.
Sure, anyone can add some authentication, not a big deal. And it’s not too hard to add SSL. I had thrown web sockets in the mix for real time updates (cf polling as a method of “updating” on end clients). So web sockets had to be secured as well. Since the node.js websocket server runs on a different port than the webserver, rather than securing two channels of communication (webserver and websockets) I implemented what I believe is the first OSHW home automation interface with real realtime two-way communication between the webserver and the clients, by marshalling the websockets through the webserver itself, and thus obfuscating the internal websocket port. Hence both the webserver and websockets traffic run on the same SSL port 433. The websocket server is obscured and any non localhost requests to it are blocked. The details of this implementation are extensively documented in this article on my blog. HTTP-Auth authentication blocks any intruders from accessing the web interface. Below is a diagram of this whole scheme.
Another important aspect of security is obfuscating the wireless requests and making it harder or impossible to decode. This is achieved with hardware AES128 encryption on the wireless transceivers such that any wireless packets to and from the end nodes cannot be decrypted by an attacker.
A more sophisticated attacker armed with a $20 RTL-SDR dongle and laptop could listen for more extended periods of time and record messages and then replay them in hope to cause a door to open for instance. Such a simple portable SDR solution (cf. portableSDR project) is elegantly explained by Alan (w2aew) in this video:
Hence the remaining gap to fill is implementing an algorithm to thwart any replay attacks for those critical commands that control physical things like appliances, lights, garage, doors, etc. This is essentially a way to salt each wireless packet with a sliding window type signature such that if it’s replayed it would be obsolete. Until this is implemented, one can tune their end node transceivers output power to only be powerful enough to reach the home gateway, which would be recommended anyway to avoid polluting the RF traffic in your neighborhood. So unless you have a curious close-by neighbor with radio knowledge who might eaves drop on your RF traffic, it would make it harder for an external intruder to get physically close to your home/location to record your traffic and try to mess with it via replay attacks.
Rolling code vulnerabilities
It seems a lot of key fob entry systems like auto locks and garage openers are using rolling code to secure their wireless communication. The transmitter increments a number in the packet with each subsequent transmission. The receiver remembers the last received token and knows what token or series of tokens are expected next. This attack involves blocking/jamming legitimate signal, then replaying the intercepted legitimate signal. Because of the jam, the receiver hears the noise and never receives the legitimate signal with the expected new token and thus the replayed message will appear legitimate.
I found this article that explains very elegantly how this all works and how the author was able to attack an auto lock using this method, via an inexpensive RTL-SDR device. Moreover, such devices as garage openers and perhaps key fob home door locks work this way. Scary.
To fix this we need to implement something that will require the receiver to be involved in each exchange. In SSL the receiver gives the sender a public key that can only be used to encrypt the message. Then the receiver uses a private key to decrypt that message. So in our case the messages are already AES128 encrypted so the messages contents are not readable to the attacker. We could then ask the receiver for a transactional token, a one time unique set of pseudorandom bytes generated by the receiver that will be used to “salt” the sender message. This technique will ensure the sender will send a different looking message every time *and also* that the receiver knows exactly what the unique expected token is. The attacker cannot spoof the token since they don’t know the secret shared AES128 encryption key. One essential assumption is that the sender message will contain the security token in addition to the actual message. The encryption will ensure that 2 messages with the same content but with different security tokens will look completely different as far as modulated RF output.
Since both receiver and sender are involved in each exchange, the receiver should expect the sender to respond very quickly with the encrypted and salted message. A short message takes a few ms to send at 55.5kbps for instance which is the default at the time of writing for the RFM69 library. Now even if an attacker records and replays messages, they are obsolete by the time they are received.