Software security is not security software. Here we're concerned with topics like authentication, access control, confidentiality, cryptography, and privilege management.
--kubelet-certificate-authority
flag.
...
spec:
containers:
- command:
- kube-apiserver
- --audit-log-maxage=50
- --audit-log-maxbackup=20
- --audit-log-maxsize=200
image: gcr.io/google_containers/kube-apiserver-amd64:v1.6.0
...
Node
authorization is a special-purpose authorization mode that specifically authorizes API requests made by Kubelets. This ensures that Kubelets have the minimal set of permissions required to operate correctly.Node
authorization mode.
...
kind: Pod
...
spec:
containers:
- command:
- kube-apiserver
...
- --authorization-mode=RBAC,Webhook
...
NodeRestriction
admission controller for a Kubernetes API server. The NodeRestriction
admission controller limits every Kubelet to modify its Node and Pod objects as well as deny access to sensitive system objects. This prevents any compromised node from gaining privileges on other nodes of a Kubernetes cluster.Pod
definition starts a Kubernetes API server without enabling the NodeRestriction
admission controller.
apiVersion: v1
kind: Pod
...
spec:
containers:
- command:
- kube-apiserver
...
- --enable-admission-plugins=PodSecurityPolicy
...
PodSecurityPolicy
admission controller is indicative of weak security controls unless there is an alternative policy enforcement tool for Kubernetes such as K-Rail, Kyverno, OPA/Gatekeeper. The PodSecurityPolicy
admission controller enforces Pod security policies that specify permissible security-related Pod attributes in a cluster. For instance, using PodSecurityPolicy
, you can forbid privileged containers and disallow privilege escalation by default whenever a Pod
is created.Pod
definition starts a Kubernetes API server without enabling the PodSecurityPolicy
admission controller.
apiVersion: v1
kind: Pod
...
spec:
containers:
- command:
- kube-apiserver
...
- --enable-admission-plugins=NodeRestriction
...
RBAC
) controls access to computer or network resources based on the roles of individual users within an organization. RBAC is the most secure authorization mode.RBAC
authorization mode.
...
kind: Pod
...
spec:
containers:
- command:
- kube-apiserver
...
- --authorization-mode=Node,Webhook
...
Pod
without any security context because there is no securityContext
field.
apiVersion: v1
kind: Pod
...
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
protocol: TCP
SecurityContextDeny
admission controller prevents Pods from setting certain SecurityContext fields that allow for privilege escalation in a Kubernetes cluster. Unless there is an alternative policy enforcement tool for Kubernetes, such as appropriate Pod security policies, the SecurityContextDeny
admission controller should be enabled.Pod
definition starts a Kubernetes API server without enabling the SecurityContextDeny
admission controller.
apiVersion: v1
kind: Pod
...
spec:
containers:
- command:
- kube-apiserver
...
- --enable-admission-plugins=NodeRestriction
...
--service-account-private-key-file
flag to specify the token signing key.--service-account-private-key-file
flag.
apiVersion: v1
kind: Pod
...
spec:
containers:
- command:
- kube-controller-manager
image: k8s.gcr.io/kube-controller-manager:v1.9.7
...
ServiceAccount
admission controller automates the service account management. Some benefits of the ServiceAccount
admission controller are to mitigate access token exfiltration with automated credential rotation and eliminate the need to persist secrets in storage. The ServiceAccount
admission controller is enabled by default but has been deliberately disabled.Pod
definition starts a Kubernetes API server and disables the ServiceAccount
admission controller.
apiVersion: v1
kind: Pod
...
spec:
containers:
- command:
- kube-apiserver
...
- --disable-admission-plugins=ServiceAccount,PodNodeSelector
...
NamespaceLifecycle
admission controller maintains the integrity of Kubernetes systems in two ways. First, it prevents objects from being created in non-existent namespaces or in namespaces undergoing termination. Second, it prevents system reserved namespaces, which contain Kubernetes critical services, from being deleted.NamespaceLifecycle
admission controller is enabled by default but the command to start the Kubernetes API server has disabled it with the --disable-admission-plugin
flag.NamespaceLifecycle
included in the --disable-admission-plugins
flag disables the NamespaceLifecycle
admission controller.
...
kind: Pod
...
spec:
containers:
- command:
- kube-apiserver
...
- --disable-admission-plugins=...,NamespaceLifecycle,...
...
--peer-auto-tls
flag to true
. As a result, the etcd instance uses self-signed certificates for TLS connections with peers.
...
spec:
containers:
- command:
...
- etcd
...
- --peer-auto-tls=true
...
root
actions without giving full root
access. The CAP_SYS_ADMIN
capability grants the permission to perform the widest possible range of system administration operations to a Pod.CAP_SYS_ADMIN
capability to a container in a Pod.
...
kind: Pod
...
spec:
containers:
...
securityContext:
capabilities:
add:
- CAP_SYS_ADMIN
- SYS_TIME
...
privileged
field allows the container almost all the same privileges as other processes running on the host. This expands the attack surface and violates the principle of running images with least privileges.privileged: true
.
...
kind: Pod
...
spec:
containers:
- name: ...
image: ...
securityContext:
privileged: true
...
12345
.
...
kind: KubeletConfiguration
...
readOnlyPort: 12345
...
default
service account. For each service account, an API access token is automatically generated and made available in a mounted directory. Attackers can use the access token in any compromised Container to gain access to insufficiently protected and security-sensitive service APIs.automountServiceAccountToken
is not defined or the configuration of the default service account contains the automountServiceAccountToken: true
setting.default
service account of a Pod are automounted if the automountServiceAccountToken
is not defined or is set to true
, as in this example.Example 2: API credentials are automounted for a Pod because there is an
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
namespace: demo-namespace
automountServiceAccountToken: true
...
automountServiceAccountToken: true
setting in the default
service account as in this example.
apiVersion: v1
kind: Pod
...
spec:
automountServiceAccountToken: true
...
--use-service-account-credentials=true
flag. This flag instructs the controller manager to start each controller using a separate service account. When used in combination with role-based access control (RBAC), this ensures that each controller runs with the minimum permissions needed to perform its tasks.--use-service-account-credentials
flag.
apiVersion: v1
kind: Pod
...
spec:
containers:
- command:
- /usr/local/bin/kube-controller-manager
image: k8s.gcr.io/kube-controller-manager:v1.9.7
...
--token-auth-file
flag, the following configuration starts a Kubernetes API server that authenticates requests by static tokens.
...
spec:
containers:
- command:
- kube-apiserver
...
- --token-auth-file=<filename>
...
chroot()
should be dropped immediately after the operation is performed.chroot()
, it must first acquire root
privilege. As soon as the privileged operation has completed, the program should drop root
privilege and return to the privilege level of the invoking user.chroot()
to restrict the application to a subset of the file system below APP_HOME
in order to prevent an attacker from using the program to gain unauthorized access to files located elsewhere. The code then opens a file specified by the user and processes the contents of the file.
...
chroot(APP_HOME);
chdir("/");
FILE* data = fopen(argv[1], "r+");
...
setuid()
with some non-zero value means the application is continuing to operate with unnecessary root
privileges. Any successful exploit carried out by an attacker against the application can now result in a privilege escalation attack because any malicious operations will be performed with the privileges of the superuser. If the application drops to the privilege level of a non-root
user, the potential for damage is substantially reduced.clone()
method.clone()
method is invoked, the constructor for the class being cloned is not invoked. Thus, if a SecurityManager or AccessController check is present in the constructor of a cloneable class, the same check must also be present in the clone method of the class. Otherwise, the security check will be bypassed when the class is cloned.SecurityManager
check in the constructor but not in the clone()
method.
public class BadSecurityCheck implements Cloneable {
private int id;
public BadSecurityCheck() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new BadPermission("BadSecurityCheck"));
}
id = 1;
}
public Object clone() throws CloneNotSupportedException {
BadSecurityCheck bsm = (BadSecurityCheck)super.clone();
return null;
}
}