We are delighted to be hosting some unique content from our friend and recovering hacker Alissa Knight who will be writing on the topic of healthcare API security. In the first article, Alissa provided a plain English explanation of FHIR from the perspective of a hacker. In this blog, Alissa covers mobile API authentication and authorization.
One of the most basic security controls you must implement to secure and harden your APIs is ensuring that every request sent to your APIs is authenticated and authorized with the latter being the most egregiously overlooked. The most prevalent implementation of authentication and authorization across FHIR APIs is SMART on FHIR created by the Computational Health Informatics Program at Boston Children’s Hospital.
I’ve successfully breached the APIs of many organizations where they authenticate API requests but fail to authorize the request to determine if the data being requested should be accessible by the user requesting it. For example, a patient requesting the patient records of a different patient would work. This is where many organizations fail as a result of attempting to secure APIs with the wrong security control, such as a Web Application Firewall (WAF). Using a WAF to secure an API is like attempting to hammer in a nail with a screwdriver - it’s simply the wrong tool for the job. WAFs are designed to look for things such as SQL injection or XSS (cross-site scripting), not logic issues such as a user requesting data for another via broken object level authorization (BOLA) vulnerabilities, as discussed in my previous article.
Authentication in APIs can be handled in a multitude of ways. Different forms of authentication mechanisms exist, such as basic authentication (the least secure) inherent to the hypertext transport protocol (HTTP). In this case, the authentication header contains an easily decoded username/password and because of the prevalence of person-in-the-middle (PITM) attacks which are designed to intercept and decrypt SSL/TLS sessions, this approach really is not good enough and shouldn’t be used anymore.
Another, more common form of authentication is the use of tokens (also referred to as API keys). These are sent in the HTTP header as well or in the actual request and, like basic auth, should be adequately protected as well via SSL/TLS encryption. This again is certainly over used and abused, with developers often hard-coding API keys in mobile apps that can be easily reverse engineered.
Today, much authentication and authorization is commonly implemented using OAuth 2.0. For this reason, I’m going to spend the most time explaining how OAuth 2 works. Simply put, OAuth 2 is a protocol that enables third-party applications to be able to talk to an HTTP service. There are four basic roles in OAuth 2 that need to be understood before I get into the mechanics of how authentication in OAuth 2 works.
The first role, client, can be a mobile application running on a mobile phone or tablet, such as a mobile health (mHealth) app or even a web app running on a web server. Clients request access from a Resource Server, which is effectively the server hosting the data being requested. An example would be a server serving protected healthcare information (PHI). The Resource Owner is effectively you, the individual actually requesting the PHI data, i.e. the patient. Finally, the Authorization Server, which as its name implies, is the server responsible for authorizing clients wanting to talk to the Resource Server via access tokens. Often, the Resource Server and Authorization Server are running on the same bare metal hardware and application. But it’s important to note here that the role of the Authorization Server is to actually authorize which clients can talk to the Resource Server by issuing tokens that should expire after a period of time, after which the client’s authorization must be renewed, typically using a refresh token.
As discussed, there are two types of tokens that a client is assigned — access tokens and refresh tokens, which the resource server is looking for the client to send when making queries for the data being served. API tokens are transmitted inside the HTTP header of the packet or in the query itself and thus should be protected from eavesdropping. Best practice is to ensure that tokens expire shortly after the duration of the longest reasonable user session . Refresh tokens are used by the client to request a new access token from the authorization server once the previous token has expired.
Access tokens are typically always limited in their scope (hopefully). In this case, the authorization server limits the rights to data being requested by the access token that’s issued to the client. For example, as a patient, my scope should only limit me to requesting the data assigned to my patient profile.
These tokens and key scope transmissions between endpoints is best illustrated in Figure 1 below.
As you can see, because of the transmission of tokens and user credentials (B) between endpoints, SSL/TLS encryption is absolutely compulsory to prevent PITM attacks in these scenarios.
Health care providers store protected healthcare information (PHI) in electronic health record (EHR) systems. Thus, when companies create applications (web or mobile) for the healthcare providers, they typically need a way to query data from the provider’s EHR system. Unfortunately, not all EHR systems are created equally. EHR systems differ greatly in the way they expect requests into the system to be formatted. This requires third-party developers to have a way to work with any EHR system no matter who the company is that makes it.
Enter SMART. SMART (Substitutable Medical Applications and Reusable Technologies) is intended to provide this compatibility third-party application designed to use SMART to be able to work with any provider’s EHR system. EHR systems need third-party apps due to their lack of complete functionality that might be needed by the provider and third-party apps need EHR systems for their data. It’s a symbiotic relationship. SMART provides a translator between by authorizing the user’s request for patient data. SMART also provides some other features, such as bundling open source libraries for developers to use and a sandbox that can generate synthetic patient data for testing so real PHI doesn't have to be used. In this way SMART can act much like a simulator of both the user and provider’s activity in launching the EHR application while also providing OAuth2 for authorization.
Despite the authorization capabilities connecting third-party applications with different SMART-compliant EHR systems, authorizing users and generating synthetic patient data isn’t enough to form the entire ecosystem of healthcare data interoperability between disparate providers and payers for data interchange. FHIR completes the Rosetta Stone between different incompatible EHR systems by creating a standard around how data served by the EHR systems is structured via APIs created by Health Level 7 International (HL7) which was mandated in the Center for Medicare and Medicaid Services (CMS) in its final rule as the standards-based approach providers and payers must build to ensure third-party and patient access to their data. SMART on top of FHIR completes this architecture for interoperability between these disparate systems, effectively adding authentication and authorization on top of FHIR APIs together with OAuth 2 — thus the name, SMART on FHIR.
In this article, we discussed authentication and authorization methods used in securing APIs. I introduced you to the different methods that developers can implement authentication to properly authenticate API requests using basic authentication, tokens, and OAuth 2.0. I demystified the concept of API tokens and keys as well as how scopes can be used to limit what data can be requested by a user’s API key. Finally, I explained SMART and how it combined with FHIR allows third-party developers to create applications that can query data from different EHR systems for payers and providers and combined with FHIR creates interoperability between these applications and systems. In the next article, I explain some of the tactics and techniques I use to conduct this type of API security research.
API Authentication. (n.d.). Apiary.Io. Retrieved May 11, 2021, from https://help.apiary.io/api_101/authentication/
Understanding OAuth2 « BubbleCode by Johann Reinke. (2016, January 22). Bubblecode. http://www.bubblecode.net/en/2016/01/22/understanding-oauth2/#What_is_OAuth2
Coy, J. (2018, September 14). SMART on FHIR: What is SMART? What is FHIR? SEP. https://sep.com/blog/smart-on-fhir-what-is-smart-what-is-fhir/
Authorization Attack - an overview | ScienceDirect Topics. (n.d.). Science Direct. Retrieved May 11, 2021, from https://www.sciencedirect.com/topics/computer-science/authorization-attack