IN THIS ARTICLE
I recently built an IoT application that streams temperature data from several devices, such as the Raspberry Pi, and charts those values in realtime. The app’s bi-directional communication is handled via PubNub’s data stream network, using our realtime SDKs. Just for fun, I’m going to show you the many ways this demo can be hacked, and how to prevent it by pre-baking security into the design.
You cannot bandaid security issues the same way you do a wound. It might suffice for a while, but soon those loopholes will get out of control. Whether it’s a hobbyist IoT project or a full-blown commercial app, security is of utmost importance.
You can run from the hackers for a while, but you can never hide from them.
This figure depicts some of the attack vectors for my IoT prototype:
Let us walk through the lifecycle of a message, from the time it is created, leaves the sender, travels through the network and finally reaches the receiver.
Hiding Data from Hackers
The first point of attack will be the hardware device itself. The devices (Arduino and Raspberry Pi) measure ambient temperature and humidity and create a message that is sent to a browser. In any case, opening inbound ports to these devices (from the browser) makes them very vulnerable to malware infections, people eavesdropping on the conversations, and modifying the data. Attackers could either listen in to understand what is happening in the network or attack that port with junk data.
Open Inbound Ports
One way to eliminate this “open inbound port problem” is to use a publish/subscribe messaging paradigm irrespective of whether MQTT, HTTP 2.0, WebSockets or CoAP is used as the communication protocol. The key is bi-directional communication between devices that open outbound ports to the network and wait for information.
How to Encrypt Your Data
You have an outbound port open, and a message has been created. The only thing left is to send the data out. If the attacker is persistent, he is going find ways to read your data. If you are a celebrity, then even more so. Whether you are building a wearable or a medical device or a chat app, users of the application will not want others reading their sensitive information.
Cryptography
Essentially you need to encrypt the data so that only intended parties are able to read them. PubNub makes it easy to do so, by just one line of code. Cryptography and encryption are really complex concepts, so it is nice when the SDKs handle them for you.
Using a combination of TLS/SSL and AES encryption, the entire communication link from device to PubNub, and PubNub to end device is covered.
Setting TLS/SSL
Enabling TLS/SSL is as easy as setting the ssl attribute to true in your instance initialization:
var pubnub = PUBNUB({ subscribe_key: 'my_subkey', publish_key: 'my_pubkey', ssl: true });
Message Layer Encryption using AES256
In order to use AES encryption, you can initialize PubNub with a default cipher key:
var pubnub = PUBNUB({ publish_key: 'my_pubkey', subscribe_key: 'my_subkey', cipher_key: 'my_cipherkey' });
Anyone with the cipher key can read the data going to and from your app if they have access to it. As the message travels through PubNub, no one can see the contents of it including PubNub.
In my application, the Raspberry Pi, and my browser both have the same cipher key, enabling them to read the data even though it is encrypted.
When I include another client through the PubNub debug console listening in on the same channel and key, he cannot see the messages unencrypted because he does not share the same cipher key.
Setting Device Permissions
At this point, you have encrypted your message and sent it out using PubNub. Another way you can get attacked is if a device spoofs a device on your network and starts publishing/subscribing to the data your devices are sending.
For instance, say you have a bunch of medical devices set up all around the hospital, monitoring different parameters and sending back this information to a central dashboard. Only administrators can see this information and control the devices. Now, this is sensitive medical information, that you do not want the wrong people to see. How do you ensure that only administration has permission to read the data, and only the medical devices have permission to send data? This becomes even more difficult as the number of devices involved in the application increase, and are present all over the world.
PubNub Access Manager
This is applicable even in my little IoT demo – the Pi and browser. Using PubNub Access Manager, I set permissions for each user, channel and application. These are read, write permissions or a combination of the two. This way, I have the authority to decide which devices can publish/subscribe and can easily grant and revoke these permissions at any time.
The console acts as the admin and only this has access to set permissions for different devices using the Secret key.
Scenario 1: Pi and browser have read (subscribe) and write (publish) permissions
This is the classic use case. Everyone has permission to do everything. The Pi is publishing data, the browser is subscribing to that data.
So now, when the Pi publishes, and the browser subscribes, they both have permission to do so.
Scenario 2: Pi can write (publish), browser cannot read (subscribe)
So when I run the program, the Pi is sending out the message, but the browser will receive a 403 Permission Denied on its side, and will not be able to read the message.
Scenario 3: The Pi can’t write (publish), the browser can read (subscribe)
Once this has been set, the Pi does not have permission to send any message. Even though the browser has permission to read those messages, there is nothing to read if the Pi cannot publish.
This way, you can set different permissions for you devices, granting and revoking them at any point as the admin user. The minute you detect any malicious or strangely behaving device in your network, you can immediate revoke any read/write permissions on that device using PubNub Access Manager. For my IoT demo, I start off with scenario 1, but the minute I detect any suspicious activity, I know I can revoke either device’s permissions to publish or subscribe.
The way this works is that PubNub acts like a bouncer at a concert. Based on the kind of ticket you have (VIP/general/field), the bouncer will let you into different parts of the concert. Having a general pass, wont give you access to the backstage area and so on. The bouncer here is PubNub. Based on the Authkey that the device provides, PubNub will give him the permissions associated with that authkey.
Monitoring Devices Remotely
As you deploy devices all around the world, it becomes imperative to monitor and control them remotely. You want to keep track of the state of your devices at any instant, and it might be physically impossible to visit each one on-site. Even in my demo, the Arduino measures temperature at my house, while the Pi is located in the office. I could be anywhere in the world, but still want to know whether these devices are on, whether they are sending data, the state at which they are in general.
When a device such as a home security monitor, oil field sensor, or home appliance disappears or stops sending and receiving data, the owner or monitoring system needs to know about it. An offline device could mean local tampering is taking place, or a broader issue like a power or Internet outage has occurred.
Using PubNub Presence, you can monitor the metadata associated with a device by setting custom states. In order to use presence, you first of all assign a Unique ID known as UUID with each device in your application. This way you can recognize the different devices remotely. Once you do that, you can monitor Presence information using PubNub Subscribe:
pubnub.subscribe({ channel : "my_channel", presence : function(m){ console.log(m) }, message : function(m){ console.log(m) } });
Once you set this, you will be notified when devices are online/offline, when they leave/join/timeout of the network and any other custom states. For instance, a remote door lock could alert its owner of a change in lock state only if the owner’s phone is not within 20 feet of the front door. Or, if an array of sensors at a solar power plant go offline, the network could immediately dispatch a technician to investigate the problem.
Putting all of the above solutions together, you get a complete end-to-end IoT security model that is robust and scalable. This image captures the complete IoT security solution.
Security for IoT is what will really drive it forward. Like we just saw, there are a lot of aspects to it – hardware, device, network security to name a few. As an application developer, you and me want to focus on developing a beautiful app. It will make life much easier if the bulk of security is handled by the network that transmits data to and from devices. This way, you can focus on building the application, scale to millions of users and also reduce any security threats to the application.