One of the major shifts in application development in recent times is the widespread adoption of microservice-based architecture (message driven or event driven computing). The benefits it offers over a traditional monolithic approach includes flexibility, resilience and scalability.
But adopting microservices architecture often creates new risks of its own. The very characteristics that make microservices so effective for modern software development also make it more vulnerable to cyber attack if the right architecture, implementation or protection is not in place. Which is why it is essential for application security requirements to be addressed at the very beginning of the software-creation process and not as an after thought.
Having both a culture of security and mutual commitment from both the application developers and security team members is essential where microservices come into play. A key part of this culture is the security team helping application developers to be aware of what is possible from a security perspective when using cloud services (and of course application developers helping the security team to understand their processes)
Speaking about microservices, Azure Service bus is a service that comes up in a lot of microservices architecture patterns in Azure and I’ll be covering some security considerations for using this service in this blog post.
What is Azure Service Bus?
It is a fully managed enterprise integration message broker. It is mainly used to decouple applications and services from each other.
Fully managed means that we don’t have to manage the underlying infrastructure, this is taken care of by Microsoft. And as part of this, some scaling, availability and security responsibilities will also be covered by the Microsoft team. For example, we don’t need to patch the underlying infrastructure for this service, that is handled by Microsoft.
That being said, we still have other aspects to take care of from a security perspective.
Azure Service Bus Security Considerations
- Authentication and Access
- Use Azure AD Authentication (where possible)
- Limit the scope of access for clients
- Store SAS tokens in key vault
- Network Security
- Implement IP Firewall
- Implement private endpoint (where possible.. Premium needed)
- Data Protection
- Implement client side encryption in code to encrypt payload (Encrypt brokered messages)
- Enhance server side encryption with your own keys
- Enable Diagnostic Logs
- Configure alerts for security sentitive events
1. Use Azure AD Authentication
There are two ways to authenticate and authorize access to Azure Service Bus resources: Using Azure Activity Directory (Azure AD) OR using Shared Access Signatures (SAS) tokens.
The best practice is not to use SAS tokens but to use Azure AD authentication instead. But what’s the reason? The risk here is that it is easier for SAS tokens to be compromised than OAuth 2.0 token used by Azure AD.
If your sender and receiver apps are part of the same organization and the apps are hosted on services that supports managed identity, use managed identity. If your apps are hosted by 3rd party or partner organizations, use service principals.
2. Limit the scope of access for clients
With Service Bus, we can assign access at the namespace level or at the queue/topic level (for both Azure AD and SAS tokens). The risk here is that assigning access at the namespace level increases the scope of impact (or blast radius) if a SAS token is compromised or an OAuth token is stolen.
There is a caveat here. There is a default namespace level root key that cannot be deleted or modified! It is called “RootManageSharedAccessKey“. And to make things even more complicated, you cannot detect easily if this key is being used as the operational logs does not capture this! So what can we do about it? We can limit who can read the key by restricting the following permission in RBAC:
- Microsoft.ServiceBus/namespaces/authorizationRules – Get Namespace Listkeys
Azure Security Center has a built-in recommendation that audits if another SAS token is created at the namespace level (Azure policy also has built in definition to audit this).
3. Store SAS tokens in key vault
If for any reason, you are still using SAS tokens (make it a priority to move away from this), make sure you are not providing the key to your application within your code, in a configuration file or in a service application setting. The risk here is that those are hotspots that attackers know to look for when hunting for credentials, Do not do this! Instead, store the token in a service like Azure Key Vault and retrieve programmatically using Key Vault references or using the SDKs.
What can we do about this? We could for example run regular checks to look in service application setttings (like Azure App Service and Azure Functions) for patterns that matches the service bus connection string. The domain suffix is “servicebus.windows.net”. The keys are 44 characters long and end with an equals sign. We could for example use the graph API to automate this across multiple subscriptions.
4. Implement IP Firewall rules
By default, Service Bus namespaces are accessible from internet as long as the request comes with valid authentication and authorization. The risk here is not necessarily that of a bruteforce attack (and thankfully Service bus does not allow anonymous access) but rather that this increases the scope of where your namespace or queues can be accessed from in the event of a token compromise. So implement this as an added layer of defense. If a key is stolen, it should not be usable to anyone in the world!
It’s important to note that you can only implement this if you are using the premium tier of Service Bus. There are certain security functionalities that are only available for the premium tier (same with using private endpoints). I wrote a custom Azure policy template that you can use to assess if you have implemented any tier oher than the premium tier. You can find and use the template from my GitHub repo. The repo also has a custom policy to assess the IP firewall rule to ensure that it has a default deny (rather than a default allow): https://github.com/davidokeyode/charis-cloud-azure-policy/tree/master/service-bus
5. Implement private endpoint
Private endpoint allows us to further restrict access on the network level by enabling access to Service Bus over a private IP in our private network. Just be aware that enabling private endpoint could negatively affect integration with Azure services like Event Grid and IoT Hub routes.
One added advantage of implementing a private endpoint is being able to audit brokered connections on the network level using a firewall which needs to be implemented in code in a normal scenario.
6. Enhance server side encryption with your own keys
Azure Service Bus Premium provides encryption of data at rest with Azure Storage Service Encryption (Azure SSE) but we can enhance this by using a customer managed key. The use case here is to enhance privacy as a customer could rotate, disable, and revoke the key used for encryption. This is only supported for the premium tier of Service Bus.
7. Implement client-side encryption in code to encrypt payload
Having data encrypted at rest on the server side is not helpful if the access token is compromised and network access is allowed. If the data being sent is of sensitive nature and no one except the receiver should be able to read it, then encrypt your payload at sender side before adding to message data the receiver can then decrypt to access the information.
There is a performance cost to this and it is common to use a symmetric key for the encryption (the symmetric key could be protected using assymetric keys for the initial key exchange). This will also help in cases where there are concerns around misconfiguration of subscription filters or access scopes. This is where you draw the last line. Even if all else fails, the data is encrypted.
8. Enable Diagnostic Logs
Diagnostic logs audits operations and actions that are conducted against the Service Bus namespace by using the API, or through management clients on the language SDK. Azure Security Center has recommendations that audits this at scale (Azure policy also has built in definition to audit this). However, there are some blind spots here that you should be aware of:
- No context around who did what
- Audited events does not include SEND or READ operations
- You can vote for this feature here: https://feedback.azure.com/forums/216926-service-bus/suggestions/7746672-azure-service-bus-should-support-web-service-and-r
- If using managed identity or service principal, non-interactive sign-in events are not logged in Azure AD sign-in logs
- You can vote for this feature here: https://feedback.azure.com/forums/169401-azure-active-directory/suggestions/31991029-make-spn-non-interactive-login-events-logged-and
9. Configure alerts for security sentitive events
If an attacker lands in an area within your environment, there are certain tactics or techniques that they could use to open backdoors or escalate their privileges or access. Configuring alerts for those techniques and tactics can help to detect intrusions in progress. Security sensitive events like the following should be alerted to in the Activity Logs and Operational logs (from diagnostic logs). The list below is by no means an exhaustive list but you get the idea.
- New IP firewall rule added or existing rule modified
- New SAS token created
- Root access key read