In this article we’ll explain why OAuth 2.0 is vital to IoT security. The internet is fundamentally an unsafe place. For every service, every API, there are users who would love nothing more than to break through the various layers of security you’ve erected.
This is no small concern, either — in the US alone, security breaches cost companies in excess of $445 Billion USD annually. As the Internet of Things (IoT) grows, this number will only climb.
The problem is our considerations concerning security are for modern web services and APIs — we rarely, if ever, twsalk about the coming wave of small connected and unconnected IoT devices that will soon make this an even greater concern.
From the connected fridge to the smartwatch, the IoT is encompassing many new web-enabled devices coming to the market. As we’re designing new API infrastructures, Jacob Ideskog believes that the “IoT is going to hit us hard if we’re not doing anything about it.”
Thankfully, there’s a great solution by the name of OAuth. OAuth 2.0 is one of the most powerful open authorization solutions available to API developers today. We’re going to discuss OAuth 2.0, how it functions, and what makes it so powerful for protecting the vast Internet of Things.
What is OAuth 2.0?
OAuth 2.0 is a token-based authentication and authorization open standard for internet communications. The solution, first proposed in 2007 in draft form by various developers from Twitter and Ma.gnolia, was codified in the OAuth Core 1.0 final draft in December of that year. OAuth was officially published as RFC 5849 in 2010, and since then, all Twitter applications — as well as many applications throughout the web — have required usage of OAuth.
OAuth 2.0 is the new framework evolution that was first published as RFC 6749 alongside a Bearer Token Usage definition in RFC 6750.
What Does OAuth Do?
While by definition OAuth is an open authentication and authorization standard, OAuth by itself does not provide any protocol for authentication. Instead, it simply provides a framework for authentication decisions and mechanisms.
“OAuth does nothing for authentication. So in order to solve this for the web, we need to add some sort of authentication server into the picture.”
That being said, it does natively function as an authorization protocol, or to be more precise, as a delegation protocol. Consider OAuth’s four actors to understand how it accomplishes this:
- Resource Owner (RO): The Resource Owner is the entity that controls the data being exposed by the API, and is, as the name suggests, the designated owner.
- Authorization Server (AS): The Security Token Service (STS) that issues, controls, and revokes tokens in the OAuth system. Also called the OAuth Server.
- Client: The application, web site, or other system that requests data on behalf of the resource owner.
- Resource Server (RS): The service that exposes and stores/sends the data; the RS is typically the API.
OAuth provides delegated access to resources in the following way. Below is a fundamental flow in OAuth 2.0 known as implicit flow:
- The Client requests access to a resource. It does this by contacting the Authorization Server.
- The Authorization Server responds to this request with a return request for data, namely the username and password.
- The Authorization Server passes this data through to an Authentication solution, which then responds to the Authorization Server with either an approval or denial.
- With an approval, the Authorization Server allows the Client to access the Resource Server.
Of note is that OAuth 2.0 supports a variety of token types. WS-Security tokens, JWT tokens, legacy tokens, custom tokens, and more can be configured and implemented across an OAuth 2.0 implementation.
Unique IoT Traits that Affect Security
Now that we understand OAuth 2.0 and the basic workflow, what does it mean for securing the Internet of Things (IoT)? Well, the IoT has a few unique caveats that need to be considered. Ideskog notes that IoT devices are typically:
- Battery powered: IoT devices are often small and serve a particular function, unlike server resources which have massive calculation-driven platforms and consistent, sanitized power flow.
- Asynchronous: They are partially or completely offline, connecting only asynchronously via hub devices or when required for functionality.
- Lean: Lastly, IoT devices usually have limited calculation capabilities, and depend on central devices and servers for this processing functionality.
Despite all of these caveats, IoT devices, are extremely attractive targets to attackers due to their known single use functions and relatively lax security.
Proof of Possession
Due to all of these caveats, the OAuth workflow is strikingly different — we are, in fact, using a methodology called Proof of Possession. Consider a healthcare scenario, in which a doctor must access an EKG IoT device. Since the IoT device cannot perform the same authentication process as a full client device can, we need to do a bit of redirection.
The start is normal. The Client sends an access request to the Authorization Server. From here, the Authorization Server contacts the Authentication Server, which prompts the Client with Authentication Data. When this is provided, the Authentication Server authenticates to the Authorization Server, which issues an authorization code to the Client:
authorization_code = XYZ
From here, we deviate from the standard OAuth workflow. The Authorization code is a one-time use proof that the user is Authenticated, and this code can be used to further contact that IoT device as an authorized device. The code is not something that can be used to directly access data as other OAuth tokens are, it is simply proof that we are who we say we are and that we’ve been authenticated and authorized.
The Client then generates a key (though this key can also be generated server side) to begin the connection process with the IoT device, sending a packet of data that looks somewhat like this:
Client_id = device123
Client_secret = supersecret
Scope = read_ekg
Audience = ekg_device_ABC
authorization _code = XYZ
Key = a_shortlived_key
With the data in hand, the Authorization Server now responds to this packet by providing an
access_token; a reference to data held in the Authorization Server memory to serve as proof of possession of both authentication and authorization:
Access_token = oddfbmd-dnndjv…
This is the final step — the client is now fully and truly authenticated. With this
access_token, the client can start a session on the IoT device. The IoT device will look at this
access_token, and pass it to the Authorization Server (if it’s a connected device) asking for verification to trust the device. When the Authorization Server accepts the verification, it passes a new key to the IoT device, which then returns it to the Client, establishing a trusted connection.
What happens if a device is unable to ask the Authorization Server for verification due to power or calculation limitations? In this case we can use something called Disconnected Flow. A key point for Disconnected Flow is unlike other OAuth 2.0 solutions, this eschews TLS (Transport Layer Security) by nature of the Resource Server being a disconnected device with intermittent connectivity and limited communication and processing power.
In this case, we’re actually shifting the parties around somewhat. The EKG machine is now the client, and another IoT device, a test tube, is the Resource Server. First, the EKG machine authenticates and authorizes in the same way as before:
Client_id = ekg_device_ABC
Client_secret = supersecret
Scope = read_result
Audience = connected_tbie_123
Token = original_token
Key = a_shortlived_key
Once this is received by the Authorization Server, the server replies not with the access token in the former structure, but instead an access_token in JWT (or JSON Web Token). This token is a by-value token, meaning it contains the data fed to it and the response. Whereas our first string referenced a memory location in the Authorization Server, the JWT has all of the data in a single key string.
From here, the JWT can be converted into other formats for easier reading by the test tube. By design, the test tube is crafted to trust the Authorization Server in a process called Pre-provisioning. Because of this, when we send the Client token in JWT (or whatever format that’s been chosen), the tube implicitly trusts the key as long as it originated from the Authorization Server, and begins a connected session with the Client.
Real Worth Authorization Failure
To see exactly why this is all so important, consider some real world authorization failures. One of the most visible failures is known as The Snappening, a leak of over 90,000 private photos and 9,000 private videos from the Snapchat application.
Most of the blame for the Snappening came from users using unauthorized third party applications to save Snaps. These third party applications did not utilize OAuth solutions, meaning when remote access users attempted to use the undocumented Snapchat URL that the third party application relied on, they were able to spoof as authorized users and retrieve content without proper token assignment.
This a great example of OAuth 2.0 vs. no implementation, as we have essentially a “control” application (Snapchat secured by OAuth) and a “test” application (the unauthorized applications tying into the undocumented API). With improper authorization integration, content was allowed to leak through an insecure system with relative ease. Had the third party application properly implemented an authorization scheme, this would never have happened.
This issue is only relevant to non-IoT things, though — it’s just a photo sharing application, right? Wrong. Consider now this same fault of security for something like an IoT button that triggers replacement business items. Attacking this device can result in man-in-the-middle attacks to capture addresses of order processing servers and even spoof orders to the tune of thousands or hundreds of thousands of dollars.
OAuth Embeds Trust into the IoT
Applying OAuth to the IoT makes it truly extensible and customizable. Using OAuth, we can build systems based on trust that use fundamentally secure resources and communications protocols. OAuth is, by design, all about trust.
This trust is key to securing the IoT. For connected devices, Proof of Possession can solve most security issues. For constrained environments by either connectivity or processing calculative power, devices can be secured using pre-provisioning that is independent of TLS, and does not require the device to be online at all times.
It should be noted that JWT, JWS, and JWE are all helpful tools, but all work with JSON. For lower processing environments, sibling binary tokens such as CWT, CWS, and CWE can be used as they cater well to building on low power and limited scope devices.
This isn’t a game — though having lax security can be convenient for innovation and experimentation, when it comes to the IoT, this is a dangerous approach. IoT devices might be underpowered and single use, but they, as a network, are powerful.
Remember that a network is only ever as secure as the sum of its parts and the weakest point of entry to its ecosystem. Failing to secure one IoT device and adopting a security system based on inherited security can result in a single IoT device comprising every device connected to it.
OAuth 2.0 can go a long way towards solving these issues.