Don’t let your services become Trojan Horses
Cloud-native applications make heavy use of services and microservice architectures. Distributed applications provide many benefits to modern application development processes and lend themselves particularly well to applications deployed in the public cloud.
But microservices can also create additional and unwanted vulnerability points that bad actors can leverage to compromise your application. A single compromised service, no matter how small, can lead to vulnerabilities that can be exploited in neighboring services, ultimately compromising them as well. A single small service can be the entry point to a massive attack that compromises your entire application.
Even if your services are in a private network—behind a cloud firewall—they should not assume the network is safe. Services within the application can still be compromised. And, like the infamous Greek Trojan Horse, a compromised service in an otherwise secure network can cause untold damage to your application.
There are many things you can do to keep your service and microservice-based application safe and secure. But two critical and often overlooked security strategies are absolutely necessary.
Overlooked Strategy #1. Authenticate all communications between services
In microservice-based applications, inter-service communications are crucial. But authentication between services is often deferred or ignored. After all, if you are inside a private, secure area (such as a cloud VPN), why do you need to authenticate communications between services? All the services are part of the same application and support each other. Why would you need to perform authentication on all requests in such an environment?
Consider a simple multi-service application.
If service A wants to talk to service B, it’s tempting to let service A send a message to service B and let service B process that message. Service B assumes the message came from service A. After all, who else is going to send the message?
The theory is simple. Assuming this application is behind a firewall since service B only gets messages from service A, there is no reason why service B should have to authenticate where the message actually came from.
This is fine when things are working normally, but it leaves you open to problems when there is a security vulnerability. What happens, for example, if a bad actor compromises some random service in your application?
Here, service C is compromised. Even though service C doesn’t normally talk to service B, the compromised service tries to reach out to find other places it can also compromise. It determines that if it sends messages to service B, it can cause service B to do some strange and unexpected actions. By trying different bad commands, it can observe how service B responds. Soon, service B also becomes compromised.
This vulnerability exists because service B is unaware that the sinister messages are coming from a random compromised service rather than from where they were supposed to come.
If instead, service B only allowed requests and commands to arrive from service A and nobody else, then a small compromised service off in the corner or your application would have a much harder time compromising service B as well, dramatically reducing the overall application impact.
By simply requiring authentication for all requests, a basic attack vector can be reduced or eliminated.
Overlooked Strategy #2. Encrypt appropriate communications between services
In every application, there is sensitive data. This might be personally identifiable information, account access credentials, customer data, financial data, or business-critical data of various forms. This data, if it were to be compromised by a bad actor, could be destructive to the business and its customers and employees.
To avoid this, whenever sensitive data is communicated from one service to another, the data needs to be sent over an encrypted data channel. This is true even if both services are inside a private network, even if access to the network is encrypted. The specific communications of sensitive data from one service to another need to be encrypted.
To understand why consider the same compromised service we discussed earlier. Even if this problematic service cannot compromise another service because it cannot get appropriately authenticated to accomplish the task, the damaged service can still eavesdrop on the communications between other services. If those communications are unencrypted, the data sent over that channel may itself become compromised.
For some data, this may not be a big issue. There is often information communicated between services that isn’t sensitive and wouldn’t be problematic if read by a bad actor. But if sensitive data is transferred unencrypted, and a bad actor has access to a service within the private network, then that sensitive data can be harvested and used by the bad actor.
If that data contains unencrypted access credentials, those credentials can be used to compromise the system further. But if the information is private customer data, the exposure creates a bad situation for your customers and a business damaging vulnerability to you.
Trojan Horses in Secure Environment
The Greeks understood how a compromised entity inside a secure environment makes that environment no longer secure. In the story of the Trojan Horse, the Greeks created a large wooden horse and gave it as a gift to the city of Troy. The people of Troy brought the wooden horse into their fortified city. Then, after the horse was within the walls of Troy, Greek soldiers jumped out to attack the now-vulnerable city from within.
Just because you are operating in a presumed secure environment, taking security precautions, including the authentication of commands and encryption of data, are prudent steps to prevent an attack from within.