How well do you track your compilers?
Containers are transforming the way IT is produced and consumed today. With the advent of Kubernetes, we have moved from a world of vast complexity to provide high-availability and load balancing, to a new world where a single chart can install, configure, distribute, and online any set of services with ease. This vast simplicity is changing the way we think about the cloud and consumption models.
This has led to a massive explosion of microservices. Instead of building large, heavy, multi-tiered applications with a trove of dependencies, we now build lightweight compiled binaries with a small rootfs wrapped in a pod. From a security perspective, legacy applications have always been problematic for their threat profiles and vulnerabilities. Keeping applications up to date and removing vulnerabilities can be a daunting task, but when combined with the management of operating systems and the dependencies necessary to run applications, the threat profile is extremely wide and almost impossible to manage to scale. This is one of the reasons why transitioning to microservices is so appealing and has led to a sharp increase in the amount of lines of code produced and services available to consume.
How safe are those microservices? Well, that depends. I have been observing the novel programming languages born from the microservices transformation and have been noticing some cause for alarm on how we address cyber threats in this new world. One specific example is the Go programming language. Moving to a minimal and simplified programming language has a ton of advantages to make code not only more extensible, but also allows for a more inclusive framework where it is far easier for developers and security professionals to collaborate closely and deliver better services with less risk to consumers. While this does decrease the threat target, the exponential increase in the number of services can lead to unknown vulnerabilities that are difficult to spot and address.
Which brings us to the initial question: how well do you track your compilers? In the case of Go, security issues are addressed in supported versions – which are the two latest versions (today, that would be 1.14 and 1.13). For Kubernetes, a simple “kubectl pod describe” of a pod will show you what version of the Go compiler was used to create the service binary. If you take an inventory of all of the pods used in production today, it wouldn’t be surprising to find a number of them on 1.11, an unsupported compiler for security updates, or older versions of 1.12 or 1.13. In addition, within the last six months, a number of CVEs were published on Go (CVE-2019-16276 and CVE-2019-14809) for net/http and net/url, two of the most commonly used packages. In order to address these vulnerabilities, development teams must update the compilers, recompile every binary using the new compiler, and redeploy the applications leveraging that binary. When applications are deployed in the tens to hundreds of thousands this can be an extremely daunting task and exposes every one of those services to zero-day exploits. How agile is your development process to address these advanced threat targets? With 6 CVEs published in 2019 – it was a busy time for managing threats to microservices.
While the world of containers has spawned a new era in service delivery, the ability to manage them to scale can still be a daunting task to reduce cyber threats.