An Analysis of Azure Managed Identities Within Serverless Environments

We examine Azure’s Managed Identities service and its security capability in a threat model as developers’ go-to feature for managing secrets and credentials.

By David Fiser

Authentication and authorization play crucial parts when securing resources. Authentication verifies that the service or user accessing the secured resources has provided valid credentials, while authorization makes sure that they have sufficient permissions for the request itself.

Broken Access Control is listed among the top 10 OWASP prevalent web application issues from 2017 to 2021, and we have previously written about the importance of secrets management used for authentication. This occurs when an unauthorized user can access, modify, delete, or perform actions within an application or system that is outside the set permissions or policies, malicious or unintended. Broken access control has become the number one concern in the organization’s list, and in this article, we discuss Azure’s Managed Identities service inside the cloud service provider (CSP) to tackle the said web application issue.

Managing system and user identities

Managed Identities for Azure allows users to authenticate certain services available within the CSP. This is done by providing the cloud application a token used for service authentication. We distinguish between two types of managed identities: system-assigned identities and user-assigned identities. To differentiate, system-assigned identities are restricted from one to the resource, which means that different user roles can’t be applied to the same resource. On the other hand, user-managed identities solve this problem and we can imagine them as user roles.

Figure 1. Usage of Managed Identities

For instance, we want to use an Azure storage account within a serverless application for saving our application records. For this purpose, we decided to use a system-managed identity.

This practically means:

  • Enable managed identities inside a serverless function
  • Grant serverless functions the necessary permissions for storage account access

Figure 2. Enabling managed identities in a serverless function

After that, we can start using the managed identity for authentication to the storage account. In the following sections, we will look at how the managed identities interface is technically implemented within the serverless environment and the corresponding security implications based on our recent research.

Managing identities in the serverless environment

To make it work, the serverless environment runs a special .NET application process named “dotnet TokenServiceContainer.dll.” This process listens on a localhost and port 8081 to accept HTTP requests. The endpoint for requesting a token is http://localhost:8081/msi/token, and the required parameters specifies that the API version used and resource identifier for which the service requests the token. Optionally, it uses “client_id,” which is a parameter used when a managed user identity token is requested. The request also needs a specific X-IDENTITY-HEADER, and the needed value is present inside IDENTITY_HEADER or an MSI_SECRET environmental variable.

After receiving this token request, the request is delegated to the endpoint within the CSP (another service) and provides the requested token. The endpoint is publicly available and is a part of the * subdomain based on the region of the serverless application. By design and public access to the endpoint the service requires authentication, and this is done using a X509 client certificate. This certificate is unique to the specific application ID (meaning the serverless function has a one-to-one pairing of certificate and app ID) and valid for 180 days. If the request is successful, it returns a JSON response with a bearer token valid for one day.

Figure 3. Managed identities inside serverless environments

From that perspective, the security standard is high, which is expected from a CSP service. However, there is one hidden danger and that is the certificate itself. The certificate can be leaked by leaking environmental variables.

The Managed Service Identity (MSI) certificate is part of the encrypted container context, which can be accessed inside using a URL-specified CONTAINER_START_CONTEXT_SAS_URI and decrypted using the CONTAINER_ENCRYPTION_KEY variable. Once the certificate is leaked, it can be used to obtain the token outside the scope of CSP services and successfully used for publicly available service endpoints as it would be called from the CSP service.

Threat model and scenario

Figure 4. PoC of getting token using leaked environmental variables from Managed Identity service

At this point, we should emphasize that to be able to abuse the retained token, a certain factor (or malicious actor) must first leak these environmental variables and there must be an assigned role within the requested resource, the pre-requisites being the identities enabled and the role set for the application. This means there are no default roles unless explicitly specified within the CSP settings.

However, as this example of potential compromise shows from a gap leaking environmental variables of a Linux endpoint, using environmental variables for storing sensitive information is not a valid secure approach as they are by default inherited into the child process. Considering that the information is available inside the environment itself and that the certificate contains all the information provided, the endpoint for getting the token now becomes publicly available. A threat actor can get the authentication token outside of the CSP's service and get all the permissions as the original user.

In this example, the token provider service within the serverless environment is running under a different user. Why is the client certificate available not only for this user in the form of a file with permissions only for that user? This allows a compromised serverless function to leak it and obtain the access token from the external service. But while the unauthorized user can’t get additional privileges other than what the function has, this is enough to conduct activities inside the environment that can have a range of damaging effects. By moving a client certificate into the security boundary of token service user and setting access permissions for the token service user as read-only, we guarantee that even in case of a compromise, the client certificate could not be leaked and used outside the CSP service without additional lateral movement.

The security chain is only as strong as its weakest parts. And while CSP services are not inherently insecure, small design weaknesses put together with improper user configurations could lead to bigger, more damaging consequences. Design applications, environments, and all their related variables with security in mind. If possible, avoid using environmental variables. Following best security practices such as applying the principle of least privilege helps to mitigate the consequences of a breach.


Like it? Add this infographic to your site:
1. Click on the box below.   2. Press Ctrl+A to select all.   3. Press Ctrl+C to copy.   4. Paste the code into your page (Ctrl+V).

Image will appear the same size as you see above.