This document demonstrates a potential security concern when using hostPath volumes in Kubernetes. It shows how a symbolic link created in a hostPath volume by one pod can expose files from the underlying node to other pods that mount the same hostPath.
Caution: Using hostPath volumes can have security implications if not managed carefully. This example illustrates one such risk.
Scenario Setup
Create a directory on the target node:
On the Kubernetes node where you intend to run the pods (e.g., student4-2 as specified in the nodeSelector), create a directory. This directory will be used as the hostPath.
# On node student4-2sudomkdir/htmlsudochmod777/html# For demonstration purposes; be cautious with permissions
Pod 1 (nginxer)
Create the first Pod manifest (nginxer.yaml):
This Pod mounts the /html directory from the node into /usr/share/nginx/html.
cat>nginxer.yaml<<EOFapiVersion: v1kind: Podmetadata: name: nginxerspec: containers: - name: nginxer image: nginx volumeMounts: - name: html mountPath: /usr/share/nginx/html ports: - containerPort: 80 nodeSelector: kubernetes.io/hostname: student4-2 # Ensure this node exists and has /html volumes: - name: html hostPath: path: /html type: DirectoryEOF
(Note: Changed the language to bash for the cat command, the inner content is YAML but created via bash)
Apply the Pod manifest:
kubectlapply-fnginxer.yaml
Create a symbolic link inside Pod 1:
Exec into nginxer and create a symbolic link from within the mounted hostPath to a file on the node (e.g., /etc/hostname which resolves to the node's hostname, but could be any file the pod's effective user on the node can access).
(Modified to be a single exec command for clarity and to ensure it runs sequentially. Also changed the link name for clarity.)
Pod 2 (nginxer2)
Create the second Pod manifest (nginxer2.yaml):
This Pod is identical to the first one and mounts the same /htmlhostPath.
(Note: Changed the language to bash for the cat command)
Apply the Pod manifest:
Access the linked content from Pod 2:
Exec into nginxer2 and observe that it can now access the content of /etc/hostname from the node via the symbolic link created by Pod 1.
(Changed to directly cat the file to show the content)
Explanation of the Issue
When nginxer creates a symbolic link (linked_hostname) within its /usr/share/nginx/html directory (which is the /html directory from the host node), that symbolic link becomes part of the node's filesystem at /html/linked_hostname.
Since nginxer2 mounts the same /htmlhostPath from the node, it sees the symbolic link created by nginxer. When nginxer2 (or any process accessing Nginx served from nginxer2) tries to read linked_hostname, the operating system on the node resolves this symbolic link. If the link points to a sensitive file on the node (e.g., /etc/shadow, service account tokens, or other configuration files), and the Nginx process (or the exec'd user) in nginxer2 has permissions to read it (often running as root inside the container, which might map to a privileged user or root on the node depending on setup), then nginxer2 can effectively read that file from the node.
This demonstrates that actions within one pod using a shared hostPath can expose node files to other pods using the same hostPath, potentially leading to information disclosure if not carefully managed.