Container security assessment: what image scanning does not see at runtime

Key takeaways
In 78% of Vulnox container security assessments, critical vulnerabilities existed in application-layer dependencies even when the base image was current — the scanner was clean because it was looking at the wrong layer (Vulnox assessment data, 2024).
Default Kubernetes service account bindings grant cluster-wide API access in most out-of-box cluster configurations. Vulnox finds over-permissioned service accounts in the majority of first-assessment Kubernetes environments.
Container image scanning in CI/CD pipelines produces a false security baseline when the same image runs in production with runtime-mounted secrets, environment variables, and sidecar containers that the scanner never saw.
Namespace-level network policies do not block pod-to-pod traffic within the same namespace by default. An attacker who compromises one pod in a namespace can reach every other pod in it without crossing a network control.
The exploit chain that produces container escape is almost never a single high-CVSS vulnerability — it is a medium-severity CVE in a running process plus an over-permissioned service account plus a missing seccomp profile. Scanners report each piece separately and the chain is invisible.
TL;DR
Container security assessments that produce clean scan reports and missed breaches are not broken tools — they are correctly scoped tools applied to the wrong problem. The scan found what it was pointed at. The breach came through the runtime configuration the scanner never ingested: the service account binding, the mounted secret, the namespace policy that did not cover lateral movement. The image is not the attack surface. The running environment is.
The cluster that passed every scan
A 120-person SaaS company running a multi-tenant Kubernetes environment had image scanning integrated into their CI/CD pipeline. Every image that shipped to production had a clean scan report. Their security posture dashboard showed zero critical findings for six consecutive months. Vulnox assessed the environment as part of a pre-Series B security review. Within the first two hours of runtime configuration analysis, we found a default service account in the application namespace bound to a ClusterRole with get, list, and watch permissions across all resource types — including secrets. Any pod running in that namespace could enumerate every secret in the cluster by querying the Kubernetes API with the automatically mounted service account token. The application pods were clean. The namespace they ran in was not.
The scanner had never been pointed at service account bindings. It scanned images. The service account was cluster configuration, not image content. The finding was invisible to every tool in the pipeline and visible in under ten minutes of manual RBAC review.
Why the scan is clean and the environment is not
Container image scanners analyze a static artifact — the image layers as they exist in the registry. They find CVEs in installed packages, misconfigurations in image build instructions, and secrets accidentally baked into layers during the build process. They do not analyze what happens when the image runs. The runtime environment introduces attack surface that did not exist in the image: environment variables injected at deployment, secrets mounted from a secrets manager, sidecar containers added by a service mesh, and Kubernetes RBAC bindings that determine what the pod''s service account can do once it is running. An image that is clean in the registry can be exploited through its runtime context without the scanner ever having seen the attack surface.
Example
In a logistics company assessment, Vulnox found a Java application image with zero scanner findings in the registry. At runtime, the deployment manifest mounted an AWS credentials file into the container at a path the application did not use — a leftover from a previous version of the deployment that someone had not cleaned up. The image was clean. The mounted credential gave any process running inside the container full S3 access across the production account. The scanner never saw the mount because it does not read deployment manifests.
The gap is architectural. Image scanners operate pre-deployment. The attack surface that matters most in Kubernetes environments is post-deployment: what the pod can reach, what it can authenticate as, what it can read from the API server, and what mounts it inherits. Closing this gap requires policy-as-code tools — OPA Gatekeeper, Kyverno — that evaluate manifests at admission time, plus runtime analysis tools that observe what containers actually do versus what they are supposed to do. Neither replaces the image scanner. Both address what the image scanner cannot see.
What runtime analysis adds to the image scan picture
Assessment base: Vulnox container security assessments, 2023-2024
Over-permissioned service accounts in default configurations
The default service account in a Kubernetes namespace has a token automatically mounted into every pod in that namespace unless explicitly disabled. In most cluster configurations Vulnox has assessed, this token carries more permissions than intended because the service account was used for a specific purpose at some point and the RBAC binding was never scoped down. Vulnox finds over-permissioned service accounts in the majority of first-assessment Kubernetes environments — not because the teams did not know about RBAC, but because the binding was added during a debugging session and never removed.
Every pod in the namespace inherits the service account permissions. An attacker who achieves code execution in any pod — through a web application vulnerability, a dependency exploit, or a supply chain compromise — immediately has authenticated API access to whatever the service account can reach. If the service account can read secrets, the attacker can read secrets from within the container without touching the host.
Application dependency vulnerabilities invisible to base image scanning
In 78% of container security assessments, Vulnox found critical vulnerabilities in application-layer dependencies — npm packages, Maven artifacts, Python wheels — in environments where the base image had been recently updated and the OS-level scan was clean. The scanner was configured to check OS packages. The application dependencies were not in its scope. Java and JavaScript ecosystems were the most consistent sources of this finding, driven by transitive dependency trees that neither the developer nor the scanner had fully enumerated.
A scanning posture that focuses on base image currency produces a false signal. The base image is the foundation, but the application layer is where most of the exploitable CVE surface lives in modern containerized applications. Expanding scanner scope to include application dependency manifests — package.json, pom.xml, requirements.txt — is a configuration change, not a tool purchase.
Namespace network policies that do not cover lateral movement
Kubernetes NetworkPolicy resources restrict ingress and egress at the pod level. But a namespace with no NetworkPolicy applied has no restrictions on pod-to-pod traffic within that namespace. In environments where teams had implemented network policies on external-facing services, Vulnox regularly found application namespaces with no intra-namespace traffic restrictions. An attacker who compromises a low-privilege pod in the namespace can initiate connections to every other pod in it.
The network policy audit that checks whether policies exist at the cluster level misses whether those policies cover intra-namespace lateral movement. The finding is not absence of network policy — it is presence of network policy that does not address the actual lateral movement path.
Runtime secrets in environment variables excluded from scan scope
Deployment manifests that inject secrets via environment variables — database connection strings, API keys, cloud provider credentials — are not analyzed by image scanners operating against the registry. Vulnox has found production deployments where AWS credentials, database passwords, and third-party API tokens were injected as plaintext environment variables directly in the Kubernetes deployment manifest, committed to the application''s GitOps repository. The image was clean. The manifest was not.
Secrets management is not a solved problem just because the image build does not contain secrets. Where the secrets land at runtime — and whether the deployment toolchain handles them securely — requires a different analysis scope than image scanning.
Why rebuilding images does not reduce your attack surface as much as you think
Common belief
Teams that rebuild container images on a regular cadence using updated base images have a materially smaller vulnerability exposure than teams that do not.
What we found
A healthcare technology company had a fully automated image rebuild pipeline running weekly, enforced by policy. Every image in production was less than seven days old. The assessment found a service account with secrets access across all namespaces, three deployment manifests with plaintext database credentials in environment variables, and no intra-namespace network policies on two of their four production namespaces. None of these findings were affected by the rebuild cadence.
Rebuilding the base reduces OS-level package vulnerability count. It does not reduce application dependency vulnerability count, because application dependencies are pinned at build time and the rebuild does not update them. It does not reduce RBAC exposure, because service account bindings are cluster configuration, not image content. It does not reduce network policy gaps, because namespace policies are applied independently of image builds. The rebuild is meaningful for one category of exposure — OS package CVEs — and has no effect on the categories that produce the most significant findings in runtime environments. Teams that have invested in rebuild automation often have higher confidence in their posture than the posture warrants, because the metric they are tracking — image age — is not correlated with the findings that actually produce exploitable paths.
What teams believe before the runtime assessment, and what it finds
We have image scanning in our CI/CD pipeline. Our images are clean before they ship.
Root cause:The pipeline scans the image. The deployment environment is a different system with additional configuration that the scanner never processes. Clean image plus insecure deployment configuration equals an exploitable runtime. The scanner cannot tell you what the image will be running next to, what it will be mounted with, or what API permissions its service account carries.
We have network policies. Our services are isolated.
Root cause:Network policies are applied at the pod level via label selectors. A namespace with no policy applied is unrestricted. A policy that restricts external ingress does not automatically restrict intra-namespace traffic. The teams that have implemented policies on their external-facing services have often not audited whether intra-namespace lateral movement is covered. The answer is usually no.
We use a managed Kubernetes service. The cloud provider handles the security defaults.
Root cause:Managed services handle the control plane. They do not configure application namespace RBAC, network policies, pod security contexts, or secrets handling. The defaults for application-layer configuration in managed Kubernetes are permissive. Managed does not mean hardened.
The container attack surface automated tools do not reach
Admission controller gaps
Policy-as-code tools like OPA Gatekeeper and Kyverno enforce security constraints at admission time — they can reject deployments that violate policy before the pod runs. But they only enforce the policies that have been written. An environment that has deployed Gatekeeper with three policies and no policy covering privileged container execution has a gap that the admission controller will not catch, because it has not been told to look for it. The presence of an admission controller is not the same as comprehensive admission policy coverage.
Init container permissions
Init containers run before the main application container and are often used for setup tasks — database migrations, configuration generation, secret fetching. They are configured separately from the main container and frequently have elevated permissions to perform their setup function. In assessments where application containers had appropriate security contexts, Vulnox found init containers running as root, with host path mounts, or with capabilities that would have been rejected if applied to the main container. The security review covered the application container. The init container was not in scope.
Helm chart default values
Helm chart deployments apply default values unless overridden. Many community charts have permissive defaults — privileged mode, host networking, broad RBAC — designed for compatibility rather than security. Teams that deploy via Helm and rely on default values inherit whatever security posture the chart author chose. The chart may have been security-reviewed at version 3.x. It is now at version 5.x and the defaults have changed. Nobody audited the diff.
Node-level escape paths
Container escapes require a vulnerability in the container runtime or a misconfiguration that grants host access — privileged mode, hostPID, hostNetwork, dangerous capabilities like CAP_SYS_ADMIN. These are pod spec settings, not image properties. They are missed by image scanners and missed by teams who audit images but not deployment manifests. Vulnox finds at least one deployment with a dangerous pod spec setting in the majority of first-assessment Kubernetes environments.
Where container attack surface is moving
Supply chain attacks targeting public Helm chart repositories will produce at least one significant breach traceable to a compromised community chart before end of 2026, accelerating enterprise adoption of private chart repositories with provenance verification.
Community Helm charts are consumed at scale with minimal verification. The artifact supply chain for Helm — chart repositories, image registries, dependency charts — has less provenance infrastructure than the npm or PyPI ecosystems, which have already produced significant supply chain incidents. The attack surface is large and the verification tooling is immature. The pattern is predictable from adjacent supply chain incidents.
Confidence: mediumA publicly confirmed breach traced to a compromised community Helm chart repository, documented in a post-incident report, before end of 2026.Policy-as-code adoption will outpace policy library development, producing a generation of Kubernetes environments with admission controllers deployed but policy coverage below 40% of their actual attack surface — creating a false hardening signal that will persist until a visible incident forces policy audit.
OPA Gatekeeper and Kyverno adoption is accelerating, driven by compliance requirements and security tooling recommendations. Policy authoring is harder than tool deployment. The gap between ''we have an admission controller'' and ''our admission controller covers the attack surface'' is large and currently has no standard measurement. Teams will report the tool deployment as a security milestone without auditing the coverage.
Confidence: highIndustry assessment data showing average policy coverage percentage in environments with deployed admission controllers, published by a major security vendor before end of 2027.
The tool that creates the problem it is supposed to solve
Container image scanning has become a compliance checkbox that gives security teams confidence in a finding category that is not where the exploitable access comes from. I have run enough container assessments to know the pattern: the image is clean, the RBAC is a disaster. The scanner produces a report that looks good. The report goes to the CISO. The environment gets a green status. The service account that can read every secret in the cluster was configured fourteen months ago by a developer who has since left, and nobody knows it exists. The tool is working correctly. The assurance it produces does not correspond to the security posture of the running environment. That is not a scanner limitation — it is a scope definition problem. The scanner scans what it was built to scan. The problem is that the thing it scans is not the thing that gets compromised.
Counterargument
The counterargument is that image scanning is one layer of a defense-in-depth architecture and was never supposed to be the complete picture. That is technically correct. In practice, when image scanning is the only instrumented layer and it produces clean reports, organizations treat it as the complete picture. The tool does not prevent that misinterpretation.
One thing to do this week
Run kubectl get clusterrolebindings,rolebindings --all-namespaces -o yaml against your cluster and grep for ''default'' service account references. Every binding that includes the default service account is a pod permission inheritance you may not have intended. Count them. If the number is more than zero and you cannot explain each one, you have an RBAC finding that your image scanner has never reported and will never report. Start there.
Further Reading
Vulnerability Assessment
comprehensive vulnerability assessmentCIS
CIS security benchmarksNIST Vulnerability Assessment Definition
NIST's vulnerability assessment definitionOWASP Web Security Testing Guide
OWASP security testing guideNVD Vulnerabilities Database
NIST National Vulnerability Database
Frequently Asked Questions
What does container image scanning miss in a Kubernetes security assessment?
Image scanning misses runtime configuration: service account RBAC bindings, secrets mounted at deployment, network policy gaps, and pod security context settings. In Vulnox assessments, exploitable findings consistently come from these runtime elements rather than the image content the scanner reviewed.
Why are Kubernetes service accounts a common security finding?
The default service account token is automatically mounted into every pod in a namespace. Vulnox finds over-permissioned default service account bindings in the majority of first-assessment Kubernetes environments — typically because a binding was added for a specific operational purpose and never scoped down after that purpose ended.
How does intra-namespace lateral movement work in Kubernetes?
A namespace with no NetworkPolicy applied has no restrictions on pod-to-pod traffic within it. An attacker who achieves code execution in any pod in the namespace can initiate connections to every other pod without crossing a network control. Policies that restrict external ingress do not automatically cover intra-namespace traffic.
Does regularly rebuilding container images improve Kubernetes security posture?
Rebuilding reduces OS-level package CVE exposure. It has no effect on service account RBAC bindings, network policy gaps, or runtime secrets in deployment manifests — which are the finding categories that produce exploitable paths in most assessed environments. Vulnox assessed a healthcare company running weekly automated rebuilds and found critical RBAC and secrets findings unaffected by the rebuild cadence.
What attack surface do Helm chart default values introduce?
Community Helm charts use permissive defaults — privileged mode, host networking, broad RBAC — designed for compatibility. Teams that deploy without overriding defaults inherit the chart author''s security posture. Default values are not reviewed when chart versions update. The security posture of a Helm-deployed application can degrade across version upgrades without any deliberate configuration change.
How do you audit Kubernetes RBAC for over-permissioned service accounts?
Run kubectl get clusterrolebindings,rolebindings --all-namespaces -o yaml and filter for default service account references. Each binding that includes the default service account is an unintended pod permission inheritance. A service account that can read secrets at cluster scope means any pod in the bound namespace can enumerate all cluster secrets using the automatically mounted token.
Related Articles

API security assessment: what automated tools miss and manual testing finds
Automated API security tools find the vulnerabilities they were designed to look for. The findings that matter in real assessments, broken object-level authorization, JWT algorithm confusion, and unauthenticated internal endpoints, require a tester who understands what the API is supposed to do before probing what it actually does.

CVSS score explained: what the metric captures, what it misses, and how to fix your prioritization
In 40% of Vulnox assessments, vulnerabilities scored CVSS 9.0 or higher were on systems with compensating controls that materially reduced the actual risk. The score was accurate. The priority order it implied was not. This guide covers how to use CVSS correctly and what to layer on top of it.

Post-breach vulnerability assessment: what the attacker left behind
Most post-breach assessments start too late and end too early. They confirm what was hit, not what the attacker mapped before they moved. The second breach usually comes from the reconnaissance that happened in the first.
Ready to Secure Your Digital Assets?
Get a comprehensive vulnerability assessment for your website today.