Security Context
El securityContext define los privilegios y controles de acceso para pods y contenedores. Una mala configuración puede permitir la escalada de privilegios, escape del contenedor o compromiso del nodo.
Pods privilegiados
Un contenedor privilegiado tiene acceso casi completo al nodo host.
jq -r '
.items[]
| select(
(.spec.containers[]?.securityContext.privileged == true)
or (.spec.initContainers[]?.securityContext.privileged == true)
)
| [.metadata.namespace, .metadata.name] | @tsv' pods.json
Ejecución como root
jq -r '
.items[]
| select(
(.spec.containers[]?.securityContext.runAsUser == 0)
or (.spec.containers[]?.securityContext.runAsNonRoot == false)
or (.spec.securityContext?.runAsUser == 0)
)
| [.metadata.namespace, .metadata.name] | @tsv' pods.json
Sin restricción de usuario (sin runAsNonRoot ni runAsUser)
Pods donde no se especifica ningún control de usuario — corren como root por defecto si la imagen no lo cambia.
jq -r '
.items[]
| select(
(.spec.securityContext?.runAsNonRoot == null)
and (.spec.securityContext?.runAsUser == null)
and (
.spec.containers[]?
| (.securityContext?.runAsNonRoot == null)
and (.securityContext?.runAsUser == null)
)
)
| [.metadata.namespace, .metadata.name] | @tsv' pods.json
Escalada de privilegios permitida
jq -r '
.items[]
| select(
(.spec.containers[]?.securityContext.allowPrivilegeEscalation == true)
or (.spec.initContainers[]?.securityContext.allowPrivilegeEscalation == true)
)
| [.metadata.namespace, .metadata.name] | @tsv' pods.json
Sin perfil Seccomp
Pods que no tienen perfil seccomp definido a nivel de pod ni de contenedor.
jq -r '
.items[]
| select(
(.spec.securityContext?.seccompProfile == null)
and (.spec.containers[]?.securityContext?.seccompProfile == null)
)
| [.metadata.namespace, .metadata.name] | @tsv' pods.json
Pods con capabilities añadidas
jq -r '
.items[]
| . as $pod
| .spec.containers[]?
| select(.securityContext.capabilities.add? | length > 0)
| [$pod.metadata.namespace, $pod.metadata.name, .name,
(.securityContext.capabilities.add | join(","))]
| @tsv' pods.json
Capabilities especialmente peligrosas
| Capability | Riesgo |
|---|---|
SYS_ADMIN | Equivale casi a root; permite montaje, namespaces, etc. |
NET_ADMIN | Control total de red del nodo |
SYS_PTRACE | Puede inyectar código en procesos del host |
DAC_OVERRIDE | Omite comprobaciones de permisos de archivos |
CAP_SETUID / CAP_SETGID | Cambio arbitrario de UID/GID |
DANGEROUS="SYS_ADMIN|NET_ADMIN|SYS_PTRACE|DAC_OVERRIDE|SETUID|SETGID|SYS_MODULE"
jq -r --arg caps "$DANGEROUS" '
.items[]
| . as $pod
| .spec.containers[]?
| select(
.securityContext.capabilities.add?
| map(test($caps)) | any
)
| [$pod.metadata.namespace, $pod.metadata.name, .name,
(.securityContext.capabilities.add | join(","))]
| @tsv' pods.json
Acceso a namespaces del host
jq -r '
.items[]
| select(
(.spec.hostPID == true)
or (.spec.hostIPC == true)
or (.spec.hostNetwork == true)
)
| [.metadata.namespace, .metadata.name,
"hostPID=\(.spec.hostPID // false)",
"hostIPC=\(.spec.hostIPC // false)",
"hostNetwork=\(.spec.hostNetwork // false)"]
| @tsv' pods.json
Sistema de archivos raíz sin modo de solo lectura
jq -r '
.items[]
| . as $pod
| .spec.containers[]?
| select((.securityContext?.readOnlyRootFilesystem // false) == false)
| [$pod.metadata.namespace, $pod.metadata.name, .name] | @tsv' pods.json
Volúmenes hostPath montados
Un hostPath puede exponer rutas sensibles del nodo (e.g., /, /etc, /var/run/docker.sock).
jq -r '
.items[]
| . as $pod
| .spec.volumes[]?
| select(.hostPath != null)
| [$pod.metadata.namespace, $pod.metadata.name, .name, .hostPath.path]
| @tsv' pods.json
Resumen de configuración insegura por pod
Muestra todos los problemas de seguridad encontrados en cada pod en una sola pasada.
jq -r '
.items[]
| . as $pod
| [
if .spec.hostPID then "hostPID" else empty end,
if .spec.hostIPC then "hostIPC" else empty end,
if .spec.hostNetwork then "hostNetwork" else empty end,
if (.spec.volumes[]? | .hostPath) then "hostPath" else empty end,
if (.spec.containers[]?.securityContext.privileged == true) then "privileged" else empty end,
if (.spec.containers[]?.securityContext.allowPrivilegeEscalation == true) then "allowPrivEsc" else empty end,
if (.spec.securityContext?.runAsUser == 0 or .spec.containers[]?.securityContext.runAsUser == 0) then "runAsRoot" else empty end
] as $flags
| select($flags | length > 0)
| [$pod.metadata.namespace, $pod.metadata.name, ($flags | join(","))]
| @tsv' pods.json