However, when a new technology is adopted rapidly, it’s important to ask if risks are being overlooked. Are there any cautions or concerns, especially in the area of security?
Containers definitely raise some new security issues. Before we go on, let’s learn more about containers.
What are containers?
Containers are units of software that package code and its dependencies to help applications run smoothly, quickly, and reliably.
The evolution of containers for security solutions
Over the years, best practices for software delivery and deployment have evolved considerably. Each successive change has made more progress toward eliminating dependencies and decoupling the software from its environment. Containers are the latest stage of this. They represent significant progress over virtual machines (VMs).
VMs allow applications to run in a variety of environments. However, they have some disadvantages, including significant internal complexity and consumption of system resources. Additionally, while a VM is intended to isolate applications from the underlying environment, the VM itself is not decoupled from it.
Compared to VMs, containers offer many advantages. A container is a standardized software package. Just as shipping containers revolutionized logistics, software containers are changing the best practices for software deployment. While VM deployment requires machine provisioning, application installation, and configuration, a container simply needs to be moved from one place to another.
Containers include code and all its dependencies. It doesn’t matter what language an application is written in; the same external interface is presented to the outside world, and the same commands will run it. Containers are now supported on all major operating systems.
Containers also facilitate microservice architectures by allowing processes/applications to be isolated at the container level. This makes it easier to keep each one independent from the others.
Are containers inherently secure?
It might seem that containers should be secure by default, especially when used as described above. Since each process has its own namespace, and is protected against breaches down to the kernel level, many common security risks would seem to be eliminated.
Nevertheless, some risks remain. Unless a process is fully standalone, with no interaction with the outside world, there will always be potential security issues. Therefore, although containers can reduce risk overall, there are still potential vulnerabilities that must be considered.
They can be categorized as follows:
The container itself
The application it contains
The application’s internal activities
The application’s external traffic
When using containers, their lifecycle must be considered. Images must be built, stored, and deployed to their target environments.
To minimize attack surfaces, a container image should include as little of the original operating system as possible. There are even minimalistic operating systems designed for this purpose. In the best case, the statically-linked application would be the only binary available.
Next, consider container management software. Orchestrators are often used for this. They make sure the services are connected, monitor the containers, and restart or scale them as needed.
However, the availability of management tools does not remove the responsibility for ensuring security. It’s important to protect the API access to the orchestrators. Fortunately, there are tools for this purpose too. For example, Kubernetes offers a Role-Based Access Control (RBAC) with secure API endpoints and different privilege levels.
Hosting an application inside a container raises numerous security issues. Some are obvious, while others might not be.
First, consider the components from which the application is built. Potential security concerns are created by the runtime, the various dependencies (like NPM packages or Python libraries), and so on.
Third-party components are usually trustworthy, but there have been examples of malicious code being uploaded to public repositories. A much more likely problem is that a threat actor finds a vulnerability within, or an exploit of, one of the components themselves.
Of course, these risks exist regardless of whether or not containers are used. But containers can be so convenient that it’s easy to start thinking of them as monolithic entities that get moved around, and then forgetting that they contain components which might need to be patched once in a while.
Thus, vigilance is still necessary. It’s important to map out dependencies, monitor announcements of patches and updates, and keep components current – not only for the application, but also for the underlying container. Adopting practices such as Infrastructure as Code (IaC) can help with much of this. Even better, fully embracing DevSecOps will improve the security posture overall.
The application’s internal activities
In this context, “internal” refers to resources that are outside the container, but still inside the perimeter: files, databases, and so on.
The goal here is simple – to limit the potential damage from a breach. Container-hosted applications should have access only to those internal resources to which access is necessary. It’s also a good idea to regularly audit those resources, to ensure that no unexpected behavior has occurred.
The application’s external traffic
An application’s interaction with its surroundings must be carefully considered and minimized. Reducing the points of entry creates a smaller attack surface.
Human error can be a source of problems here. This isn’t necessarily common, but its consequences can be severe. One accidentally exposed endpoint – one that was left open during development and then later forgotten about – can negate all the hardening that is done elsewhere.
Another important practice is to always protect the traffic with transport layer encryption (TLS), both internally and externally. Not only will this make eavesdropping difficult, but it also allows authenticating two services against each other. TLS is a “must-have” today, especially for securing external APIs, but there are still organizations today who aren’t using it.
Lastly, consider what is probably the most important security issue of all – the composition of traffic. A large portion of incoming requests will be malicious.
Some attack traffic is straightforward to mitigate. For example, older exploits with well-known signatures can be filtered by most web application firewalls (WAFs). Many DDoS attacks are also easily recognized, and can be mitigated without affecting the responsiveness of your applications.
Other attacks can be problematic, such as:
Container security solutions that do not include a full positive security model will not protect against the newest exploits (especially zero-days).
On-premise DDoS solutions cannot filter volumetric attacks until after the traffic has already passed through (and potentially overwhelmed) the incoming Internet pipe.
Even more complicated problems arise from application-specific vulnerabilities. Software evolves rapidly today, enabled by methodologies such as DevOps. Simultaneously, APIs can grow quickly, often while needing to maintain backwards compatibility. The result is that attack surfaces have a tendency to expand and become more complex over time.
Of course, these problems are not unique to container-hosted applications. But containers can sometimes make them worse. Traditional approaches to security are based on traditional network architectures, but containers aren’t limited to these environments. In fact, some of the benefits of containers cannot be realized in those circumstances.
Thus, in order to use containers to their fullest advantage – and to do so securely – a different approach to security is required.
How the Cloud can help
When containers are used to run applications in the Cloud, this simplifies many of the security issues discussed above.
For example, Cloud applications naturally lend themselves to using microservices, with all the benefits that they bring. They can take advantage of managed solutions to solve challenges such as orchestration setup. Cloud resources can be autoscaled, responding appropriately to changes in workload.
The ideal goal of all this is Cloud-native computing, where microservices are packaged into Cloud-hosted containers, having been developed and deployed via agile DevOps processes. A logical extension is to also embrace cloud-native security.
Cloud security solutions can scrub traffic in the cloud, before it reaches the application itself. Potential vulnerabilities within a container or application become less important, because threat actors cannot reach their targets directly; all incoming requests pass through the security solution first. Volumetric attacks are unable to overwhelm the target’s resources.
Technologies such as machine learning can be leveraged to detect and block complex threats, such as the latest generations of bots. And solutions with full positive security models can ingest API schemas and even adapt dynamically to changes in web application and API usage, thus facilitating DevOps while also mitigating zero-day exploits.
In the Cloud, containers can use virtual private Clouds (VPCs) for better isolation. The best cloud security solutions take full advantage of this; they run in unique, dedicated VPCs for each protected network. This allows for near-zero latency (since the VPC can be geolocated immediately in front of the network it’s protecting), maximum privacy (since traffic is processed only within the perimeter, and remains encrypted at all times outside of it), and eliminates multi-tenancy vulnerabilities that exist with shared-resource architectures.
Containers offer many advantages. Although they include a few new security issues, these are not severe. Addressing them carefully will allow organizations to enjoy the numerous benefits of containers, without adding security risks. This can be especially true when containers are used in Cloud-native architectures, where they can also take advantage of best-of-breed security solutions.
Maksim Blishchik is Senior DevOps Engineer at Reblaze, a cloud-based, comprehensive security solution for web applications and APIs. Maksim is in charge of Cloud Architecture for Reblaze’s global network of operations, from planning to deployment, across all major cloud providers.