I suffer the struggle many others do. It’s a systemic issue that’s not really talked about much. The issue I’m talking about is the inconvenience of turning my lamp off and then proceeding to stumble around in the dark to get to my bed. I set out to solve this problem by automating my lamp with a Raspberry Pi, a relay, and a simple web application. The setup can be seen in the photo below:
Those who have worked with electronics before know this setup is not very technically challenging, but I wasn’t going for anything too fancy. My goal was to create a simple web application that could turn my lights on and off, which can be seen in the code below. This code also includes an alarm clock which operates by flashing my lights every morning at a preset time.
Interested in trying it? Just pull it down from GitHub: https://github.com/dxa4481/insecureLamp
This is exactly the way I wrote the code, and it’s exactly what’s running on my Pi right now. Publishing this to an extent makes me feel naked. The reason, it’s bad code. It has a number of design issues and security problems.
I’m going to be addressing each security issue individually, but let’s start by identifying the cost of running an insecure lamp. What are the consequences?
In the worst case, someone who isn’t me can turn my lights on and off. The most likely attacker would be my roommate who is also a security engineer.
In the shoes of my evil roommate
What can my roommate do to turn my lights on and off? First my roommate needs to learn about my lamp. To do this, he can simply perform a port scan of our network or pull the information off the router. An Nmap scan of the network will reveal the following information:
Starting Nmap 7.01 ( https://nmap.org ) at 2016-01-20 22:11 CSTNmap scan report for piHost is up (0.0057s latency).Not shown: 998 closed portsPORT STATE SERVICE VERSION22/tcp open ssh OpenSSH 6.7p1 Raspbian 5 (protocol 2.0)5000/tcp open http Werkzeug httpd 0.11.3 (Python 2.7.9)Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernelService detection performed. Please report any incorrect results at https://nmap.org/submit/ .Nmap done: 1 IP address (1 host up) scanned in 13.39 seconds
From this, my roommate can see a Raspbian device running an http server. After making a request to port 5000, it’s pretty much game over.
How can I protect my lamp?
One simple thing I could do is require authentication on the endpoints.
If I required myself to type in my password every time I wanted to turn my light on and off, it would be really annoying, so I would need to setup a session management system to keep myself logged in on my devices.
There is a problem I haven’t addressed yet though, and that’s the fact the web server is not running SSL. Why is this an issue? My roommate exists on the same network as me, so it’s trivial for him to capture my traffic and session token.
To solve this I can do one of two things:
- Use a self-signed cert or a cert from a CA I create
- Buy a domain name and a certificate
The first option requires manually adding a new trusted cert or CA to each device I want to use this web application on. The second option costs money. Neither option really seemed that appealing to me.
After one of those options is selected, there’s one more thing that should be added to my code, and that’s CSRF protection. With the ability to ARP poison our home network, and man in the middle my traffic, my roommate could very easily drop a CSRF payload onto an insecure page I attempt to load, and cause my browser to send my session token over to my lamp, turning the lights on or off.
The last thing that should be done is provide protection to the device itself. My roommate lives in my apartment, and he could gain physical access to the device. If I had a certificate on the device, he could simply mount the Pi’s SD card and copy the cert. To solve this I can setup LUKS full disk encryption, but that can be very resource intensive on a Raspberry Pi.
So let’s review. Setting up my automatic lamp and programming it took about half an hour of work.
Securing the lamp would require:
- Implementing session management
- Implementing CSRF management
- Adding a trusted cert or CA to all devices or buying a domain and cert
- Installing LUKS on my Raspberry Pi
This is a lot more than half an hour of work.
I think this is the problem most developers face when dealing with security. It’s very easy to get working code, but writing good and secure code is a real challenge. In a world of a growing number of interconnected devices, where our lamps are networked and automatic and our cars drive themselves, we need be aware of this and take into consideration that every connected device has had a developer facing similar issues to the ones I’m facing right now.
Will my roommate take control of my lamp and turn it on and off? I hope not.
That is why my lamp is insecure.
Edit: My roommate won’t stop turning my lamp on and off