Skip to content
Sedat Özdemir
Writing

container-security

Is the Ship Sinking? Lost Security Between Container Layers and Lessons from the Field

Let’s debunk the myth that containers are inherently secure. From root user illusions to supply chain risks, I’m diving into why your 'isolated' environments might be more vulnerable than you think.

Sedat Özdemir
· 4 dk read

Hey there, if your coffee is ready, let's talk about some of our 'modern' headaches today. We used to think of security like building a physical fortress: a solid firewall, tight IDS/IPS, and a 'bouncer' at the door (WAF). But the world has changed. Nobody is chasing monolithic giant servers anymore; we break everything into pieces and pack them into little containers. But is the world inside those little packages really as sterile as it seems? Or did we just trap our problems in smaller boxes?

Let’s start with a trend: For a while, the 'I have a virtual machine (VM), so I’m isolated' mindset was huge. Now, the popular delusion is 'I use containers, they’re ephemeral anyway, so what if an attacker gets in?' The bitter truth we see in the field is that attackers spend only seconds escaping those ephemeral containers to turn your entire cluster into their playground. Let’s look at why this ship is leaking, drawing from tests we’ve conducted at testCompany and real-life scenarios.

1. The Obsession with Being 'Root' and Illusions

The biggest misconception in the container world is believing that the root user inside a container doesn't have the same power as the root user outside. Technically, thanks to Linux namespaces, there is isolation, yes—but that isolation hangs by a thread. If you didn't add a command specifying a USER at the bottom of your Dockerfile, that application runs with root privileges by default.

You know what my favorite scenario as an attacker is? Finding an RCE (Remote Code Execution) on a public-facing web application, getting inside, and seeing the response root when I type whoami. Why? Because if I’m root inside the container, it means I have all the permissions I need to push kernel vulnerabilities and perform a 'container escape.'

Flawed Dockerfile Example (Defanged):

FROM node:14
WORKDIR /app
COPY . .
RUN npm install
# USER not defined, application is running as root!
CMD ["node", "app.js"]

The Right Approach:

FROM node:14-slim
# Removed unnecessary tools, kept only what we need
RUN groupadd -r appuser && useradd -r -g appuser appuser
WORKDIR /app
COPY --chown=appuser:appuser . .
USER appuser
CMD ["node", "app.js"]

2. Supply Chain: Bringing the Trojan Horse in Yourself

Trusting only the code you wrote isn't enough. When you say FROM python:3.9, you are essentially saying 'yes' to hundreds of libraries and operating system layers inside that image. In a recent Red Team scenario, we saw how we could perform lateral movement just by using an old, forgotten, and unused version of curl left inside an image.

Images are layered. Sensitive data you delete in one layer (like an API key) might still be sitting right there in a previous layer. Have you ever tried the docker history command on your own images? Give it a shot; sometimes you might find a 'hardcoded credential' disaster hiding in there.

Checklist:

  • Use distroless or minimal base images.
  • Scan your images for vulnerabilities (SCA) during the CI/CD phase.
  • Never pass secrets via environment variables; use secret management solutions.

Related posts