Skip to content

Path traversal in ReadFile() via container label escapes proc namespace boundary #3851

@Ryujiyasu

Description

@Ryujiyasu

Summary

In manager/container.go, the ReadFile() function uses path.Join with a user-controlled filepath parameter derived from Docker container labels, without any prefix validation. This enables path traversal from within a container's namespace to arbitrary files on the host.

Vulnerable Code

File: cadvisor/manager/container.go:250-272

func (cd *containerData) ReadFile(filepath string, inHostNamespace bool) ([]byte, error) {
    pids, err := cd.getContainerPids(inHostNamespace)
    rootfs := "/"
    if !inHostNamespace {
        rootfs = "/rootfs"
    }
    for _, pid := range pids {
        filePath := path.Join(rootfs, "/proc", pid, "/root", filepath)
        // ↑ NO prefix check: path.Join resolves ".." → escapes proc/PID/root/ boundary
        data, err := os.ReadFile(filePath)

The filepath comes from the io.cadvisor.metric.* container label. With a label value of ../../../../etc/shadow, path.Join resolves to /etc/shadow on the host.

Proof:

path.Join("/", "/proc", "1234", "/root", "../../../../etc/shadow")
// → "/etc/shadow"   ← host shadow file, not container's

path.Join("/rootfs", "/proc", "1234", "/root", "../../../../proc/1/environ")
// → "/proc/1/environ"   ← host init process environment (may contain secrets)

Attack Scenario

  1. Attacker deploys container with label: io.cadvisor.metric.steal=../../../../etc/shadow
  2. cAdvisor calls ReadFile("../../../../etc/shadow", inHostNamespace) for that container
  3. path.Join resolves to host /etc/shadow — file is read by cAdvisor (running as root in a DaemonSet)
  4. Contents leak into cAdvisor logs or error messages

Suggested Fix

After path.Join, validate that filePath still starts with the expected prefix (rootfs + "/proc/" + pid + "/root/"). Reject any path that escapes the container's root namespace.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions