As a security practitioner, part of the job is to keep up with the changes in technology. This is certainly no easy task as things are changing at breakneck speed. New architectural concepts, the rise of cloud, new data processing models, lots more data, and dynamic environments: all these things make the future bright albeit complex. Meanwhile, as organizations are moving towards the light of these shiny new possibilities many are also maintaining out of date infrastructure and applications well beyond their intended life cycles to maintain the capabilities for a service the business still relies on. What we're left with now is the heterogeneous mixture of the old and the new and understanding both is critical to information security.
This week's blog topic is on the new, well sort of new, concept of microservices. I have found this to be a challenge for many a security team and I think one that is solvable mostly by just gaining understanding. This article intends to outline what exactly a microservice is, understanding why so many developers are moving towards this type of architecture, and finally what we as security practitioners need to know to protect these services and the data within. Many of the concepts and threats discussed in this article come from the NIST SP 800-204 written by Ramaswamy Chandramouli so credit where credit is due for a terrific write-up.
What is a Microservice?
The concept of using microservices is really a software design or architectural strategy for building applications. It builds on the idea of modularization which has been in place for a very long time. Traditionally, modularization would occur within a singular application at the language level in the form of methods or functions. Each function would typically have a single or small set of jobs to perform and may have data inputs and outputs. Microservices take that a step forward and develop wholly self-contained applications to perform that single function and run separately from the other software components. These microservices don't have to run on the same hardware or even be written in the same language as the rest of the overall application. Rather than an internal function call within the traditional model, microservices communicate with each other via Application Programming Interface (API) calls or sometimes a publish/subscribe model like Kafka. Microservices are designed for failure tolerance, scalability, independence, and flexibility.
So why the sudden shift to microservices? Once you begin to understand the concepts behind microservices the advantages are apparent.
- Scaling: With each component of the overall software being run completely independent you can scale them independently. We've likely all encountered a piece of software that is hung during a particular stage of processing. What if just that function could be scaled out to multiple instances running on disparate hardware resources whether on-premise, cloud, or both? The rest of the application could remain scaled down while just the portion that needs the extra resources gets them.
- Isolation: When a microservice suffers an outage for whatever reason it doesn't necessarily mean the entire application will go down. In fact, likely only a portion of the overall app's functionality will go down and because microservices are designed to be as state free as possible once that microservice is restored it will simply pick up the unprocessed data in the queue and keep on chugging.
- Developer independence: If you are working on a large application that is split into separate microservices you can divvy out the work to entirely different teams. The microservices don't have to run on the same platforms as one another, or even be written in the same language as we might expect in traditional software engineering models.
Although there are more advantages to discuss this gives you an idea of why so many are interested in this model. There are, however, some disadvantages as well:
- Monitoring and Availability Challenges: Although microservices are designed to be failure tolerant the overall application must be designed to have any particular microservice become unavailable. This also presents a challenge in monitoring because all the microservices must be monitored separately and then centrally aggregated to monitor overall application health.
- Version Management: Microservices are updated independently and in some cases calls to the microservice may require a specific version of that service which can present a challenge.
- Secure API: As opposed to the traditional model where data is being passed within memory in the stack of the software being run, data in microservices is generally passed via API calls. This means that the data is now traversing the network layer and further security controls are required to protect that data in transit.
I want to preface by saying that many of the existing threats to application security are still present with implementing via microservices. This includes all the goodies in the OWASP top ten as well as all the infrastructure security hygiene required based on the type of platform you are running these microservices on. For example, if you are running containers in a cloud, you still need to consider the security of the containers as well as the secure configuration of your cloud instances. I will only be focusing on the threats are specific to microservices themselves so just be aware you need to consider this plus the security considerations down the stack as well.
One thing to consider is the registration and de-registration of services. This concept of attacking this is not new, it's just a variation of Man in the Middle (MitM). The idea being, depending on how microservice nodes are added and removed from the overall application infrastructure, is it possible for a malicious node to register itself to begin receiving or sending data from other microservices. There needs to be some form of mutual authentication in place between microservices to verify the identity of nodes.
Another factor with microservices is the increase in complexity and surface area. Where there once were only a few input and output nodes within a traditional software architecture now each microservice must be able to accept inter-process communication (IPC) generally in the form of APIs. We have a lot of developers that are trained to not trust data coming into the system from the outside world, however, the outside world in microservice architecture is everything but your module. We must implement proper data validation (should have been doing this anyway) at every microservice layer.
In addition, there are more moving parts as services must interact with each other through the network. This means developers must be conscious of how data is being transported through the network and it's being secured in transit. Securing the front-end UI with SSL is not the only consideration in this model, you must also consider data in transit security for IPC as well.
Many of the security challenges we face when implementing microservices are no different than any other service. First of all, we need strong authentication mechanisms in place. For microservices, that typically starts with API keys that provide identity and authenticate a request to a microservices API gateway. Authentication tokens using Security Assertion Markup Language (SAML) or OAuth can help facilitate authentication decisions, especially when using a centralized source of authority for microservice transactions. Also, policy-based access decisions are required to maintain appropriate access levels for various microservices in the application as a whole. Determining what microservices are authorized to call which API functions would be a product of these access policies.
Securing communications as we mentioned previously is critical to the security of applications leveraging microservices. You will need to consider not just communications traffic from the client to the application, but the traffic to and from microservices communicating via API. You also need to consider any persistent storage solutions that maintain data or state information such as databases. Mapping these dataflows out and understanding what information is being sent to which components go a long way in determining a security strategy appropriate for your overall application. The key here is to implement SSL/TLS everywhere sensitive data is traversing any network. Implementing an API gateway can help facilitate this because it acts as a liaison between both client to service and service to service communication. The API gateway can not only enforce secure communications but also enforce the access control policies we discussed.
Monitoring is challenging, however very important when implementing a microservice application. Due to the isolation and modularization of each service, there is a lot to monitor, however, due to the interdependence between services it's very important to aggregate monitoring information to a centralized dashboard to provide a complete overview of the health of the application and to detect any cascading failures that may occur. You may also want to implement a circuit breaker function that understands the interdependence between services so that if a microservice becomes unavailable any microservices that depend on that service are also taken offline to prevent interruption or partial processing of business logic. This circuit breaker functionality can be triggered from your centralized monitoring platform and enforced again through the use of an API Gateway.
Although this blog just scratches the surface of microservice security strategy, hopefully, it provides you with a better understanding of this technology. Microservices provide a lot of benefits to developers and operations teams which makes it easy to understand the trend towards this model. As security practitioners we can see a lot of parallels in security best practices, we just need to re-think some of the implementations of these principles and work with our dev and ops counterparts to come up with workable solutions.
Written by Zach Turpen
Zach Turpen is a Cybersecurity Consultant at TechGuard Security where he conducts penetration tests, vulnerability assessments, social engineering exercises and develops detailed incident response procedures. With experience spanning over 6 years in a Fortune 100 environment he is also CISSP, CEH, GSEC, Security+, Splunk, Rapid 7, ITIL and VMware certified. Zach graduated Summa Cum Laude from McKendree University with a bachelor’s degree in Computer Information Systems. He has worked on the front line of security as an Incident Responder, as a Lead Security Engineer implementing multi-million-dollar projects (SIEM, NGAV, Web Proxies, NGFW) and as a Security Architect migrating business applications to the cloud. In his spare time Zach enjoys spending time with his wife and two kids, gardening and kayak fishing.