Skip to content

Commit

Permalink
Merge pull request #1683 from kubescape/fix/mask-data
Browse files Browse the repository at this point in the history
Mask all containers data
  • Loading branch information
slashben committed May 9, 2024
2 parents da6faa3 + b2b37f6 commit 7f9f6d3
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 13 deletions.
37 changes: 31 additions & 6 deletions core/pkg/opaprocessor/processorhandlerutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package opaprocessor
import (
"context"

corev1 "k8s.io/api/core/v1"

logger "github.com/kubescape/go-logger"
"github.com/kubescape/k8s-interface/k8sinterface"
"github.com/kubescape/k8s-interface/workloadinterface"
Expand Down Expand Up @@ -97,7 +99,7 @@ func isEmptyResources(counters reportsummary.ICounters) bool {

func getAllSupportedObjects(k8sResources cautils.K8SResources, externalResources cautils.ExternalResources, allResources map[string]workloadinterface.IMetadata, rule *reporthandling.PolicyRule) map[string][]workloadinterface.IMetadata {
k8sObjects := getKubernetesObjects(k8sResources, allResources, rule.Match)
externalObjs := getKubenetesObjectsFromExternalResources(externalResources, allResources, rule.DynamicMatch)
externalObjs := getKubernetesObjectsFromExternalResources(externalResources, allResources, rule.DynamicMatch)
if len(externalObjs) > 0 {
l, ok := k8sObjects[clusterScope]
if !ok {
Expand All @@ -109,7 +111,7 @@ func getAllSupportedObjects(k8sResources cautils.K8SResources, externalResources
return k8sObjects
}

func getKubenetesObjectsFromExternalResources(externalResources cautils.ExternalResources, allResources map[string]workloadinterface.IMetadata, match []reporthandling.RuleMatchObjects) []workloadinterface.IMetadata {
func getKubernetesObjectsFromExternalResources(externalResources cautils.ExternalResources, allResources map[string]workloadinterface.IMetadata, match []reporthandling.RuleMatchObjects) []workloadinterface.IMetadata {
k8sObjects := []workloadinterface.IMetadata{}

for m := range match {
Expand Down Expand Up @@ -215,16 +217,39 @@ func removePodData(workload workloadinterface.IWorkload) {
workloadinterface.RemoveFromMap(workload.GetObject(), "metadata", "managedFields")
workloadinterface.RemoveFromMap(workload.GetObject(), "status")

containers, err := workload.GetContainers()
if err != nil || len(containers) == 0 {
return
// containers
if containers, err := workload.GetContainers(); err == nil && len(containers) > 0 {
removeContainersData(containers)
workloadinterface.SetInMap(workload.GetObject(), workloadinterface.PodSpec(workload.GetKind()), "containers", containers)
}

// init containers

if initContainers, err := workload.GetInitContainers(); err == nil && len(initContainers) > 0 {
removeContainersData(initContainers)
workloadinterface.SetInMap(workload.GetObject(), workloadinterface.PodSpec(workload.GetKind()), "initContainers", initContainers)
}

// ephemeral containers
if ephemeralContainers, err := workload.GetEphemeralContainers(); err == nil && len(ephemeralContainers) > 0 {
removeEphemeralContainersData(ephemeralContainers)
workloadinterface.SetInMap(workload.GetObject(), workloadinterface.PodSpec(workload.GetKind()), "ephemeralContainers", ephemeralContainers)
}
}

func removeContainersData(containers []corev1.Container) {
for i := range containers {
for j := range containers[i].Env {
containers[i].Env[j].Value = "XXXXXX"
}
}
}
func removeEphemeralContainersData(containers []corev1.EphemeralContainer) {
for i := range containers {
for j := range containers[i].Env {
containers[i].Env[j].Value = "XXXXXX"
}
}
workloadinterface.SetInMap(workload.GetObject(), workloadinterface.PodSpec(workload.GetKind()), "containers", containers)
}

func ruleData(rule *reporthandling.PolicyRule) string {
Expand Down
145 changes: 138 additions & 7 deletions core/pkg/opaprocessor/processorhandlerutils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,152 @@ package opaprocessor
import (
"testing"

corev1 "k8s.io/api/core/v1"

"github.com/stretchr/testify/assert"

"github.com/kubescape/k8s-interface/workloadinterface"
)

func TestRemoveData(t *testing.T) {
type args struct {
w string
}
tests := []struct {
name string
args args
}{
{
name: "remove data",
args: args{
w: `{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"name":"demoservice-server", "annotations": {"name": "kubectl.kubernetes.io/last-applied-configuration", "value": "blabla"}},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"demoservice-server"}},"template":{"metadata":{"creationTimestamp":null,"labels":{"app":"demoservice-server"}},"spec":{"containers":[{"env":[{"name":"SERVER_PORT","value":"8089"},{"name":"SLEEP_DURATION","value":"1"},{"name":"DEMO_FOLDERS","value":"/app"},{"name":"ARMO_TEST_NAME","value":"auto_attach_deployment"},{"name":"CAA_ENABLE_CRASH_REPORTER","value":"1"}],"image":"quay.io/armosec/demoservice:v25","imagePullPolicy":"IfNotPresent","name":"demoservice","ports":[{"containerPort":8089,"protocol":"TCP"}],"resources":{},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File"}],"dnsPolicy":"ClusterFirst","restartPolicy":"Always","schedulerName":"default-scheduler","securityContext":{},"terminationGracePeriodSeconds":30}}}}`,
},
},
{
name: "remove data with init containers and ephemeral containers",
args: args{
w: `{"apiVersion": "v1", "kind": "Pod", "metadata": {"name": "example-pod", "namespace": "default"}, "spec": {"containers": [{"name": "container1", "image": "nginx", "ports": [{"containerPort": 80}], "env": [{"name": "CONTAINER_ENV", "value": "container_value"}]}], "initContainers": [{"name": "init-container1", "image": "busybox", "command": ["sh", "-c", "echo 'Init Container'"], "env": [{"name": "INIT_CONTAINER_ENV", "value": "init_container_value"}]}], "ephemeralContainers": [{"name": "debug-container", "image": "busybox", "command": ["sh", "-c", "echo 'Ephemeral Container'"], "targetContainerName": "container1", "env": [{"name": "EPHEMERAL_CONTAINER_ENV", "value": "ephemeral_container_value"}]}]}}`,
},
},
{
name: "remove secret data",
args: args{
w: `{"apiVersion": "v1", "kind": "Secret", "metadata": {"name": "example-secret", "namespace": "default", "annotations": {"kubectl.kubernetes.io/last-applied-configuration": "{}"}}, "type": "Opaque", "data": {"username": "dXNlcm5hbWU=", "password": "cGFzc3dvcmQ="}}`,
},
},
{
name: "remove configMap data",
args: args{
w: `{"apiVersion": "v1", "kind": "ConfigMap", "metadata": {"name": "example-configmap", "namespace": "default", "annotations": {"kubectl.kubernetes.io/last-applied-configuration": "{}"}}, "data": {"exampleKey": "exampleValue"}}`,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
obj, _ := workloadinterface.NewWorkload([]byte(tt.args.w))
removeData(obj)

workload := workloadinterface.NewWorkloadObj(obj.GetObject())

_, found := workload.GetAnnotation("kubectl.kubernetes.io/last-applied-configuration")
assert.False(t, found)

_, found = workloadinterface.InspectMap(workload.GetObject(), "metadata", "managedFields")
assert.False(t, found)

_, found = workloadinterface.InspectMap(workload.GetObject(), "status")
assert.False(t, found)

if d, ok := workloadinterface.InspectMap(workload.GetObject(), "data"); ok {
data, ok := d.(map[string]interface{})
assert.True(t, ok)
for key := range data {
assert.Equal(t, "XXXXXX", data[key])
}
}

if c, _ := workload.GetContainers(); c != nil {
for i := range c {
for _, e := range c[i].Env {
assert.Equal(t, "XXXXXX", e.Value, e.Name)
}
}
}

if ic, _ := workload.GetInitContainers(); ic != nil {
for i := range ic {
for _, e := range ic[i].Env {
assert.Equal(t, "XXXXXX", e.Value, e.Name)
}
}
}

if ec, _ := workload.GetEphemeralContainers(); ec != nil {
for i := range ec {
for _, e := range ec[i].Env {
assert.Equal(t, "XXXXXX", e.Value, e.Name)
}
}
}
})
}
}

func TestRemoveContainersData(t *testing.T) {
containers := []corev1.Container{
{
Env: []corev1.EnvVar{
{
Name: "TEST_ENV",
Value: "test_value",
},
{
Name: "ENV_2",
Value: "bla",
},
{
Name: "EMPTY_ENV",
Value: "",
},
},
},
}

removeContainersData(containers)

for _, c := range containers {
for _, e := range c.Env {
assert.Equal(t, "XXXXXX", e.Value)
}
}
}

func TestRemoveEphemeralContainersData(t *testing.T) {
containers := []corev1.EphemeralContainer{
{
EphemeralContainerCommon: corev1.EphemeralContainerCommon{
Env: []corev1.EnvVar{
{
Name: "TEST_ENV",
Value: "test_value",
},
{
Name: "ENV_2",
Value: "bla",
},
{
Name: "EMPTY_ENV",
Value: "",
},
},
},
},
}

w := `{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"name":"demoservice-server"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"demoservice-server"}},"template":{"metadata":{"creationTimestamp":null,"labels":{"app":"demoservice-server"}},"spec":{"containers":[{"env":[{"name":"SERVER_PORT","value":"8089"},{"name":"SLEEP_DURATION","value":"1"},{"name":"DEMO_FOLDERS","value":"/app"},{"name":"ARMO_TEST_NAME","value":"auto_attach_deployment"},{"name":"CAA_ENABLE_CRASH_REPORTER","value":"1"}],"image":"quay.io/armosec/demoservice:v25","imagePullPolicy":"IfNotPresent","name":"demoservice","ports":[{"containerPort":8089,"protocol":"TCP"}],"resources":{},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File"}],"dnsPolicy":"ClusterFirst","restartPolicy":"Always","schedulerName":"default-scheduler","securityContext":{},"terminationGracePeriodSeconds":30}}}}`
obj, _ := workloadinterface.NewWorkload([]byte(w))
removeData(obj)
removeEphemeralContainersData(containers)

workload := workloadinterface.NewWorkloadObj(obj.GetObject())
c, _ := workload.GetContainers()
for i := range c {
for _, e := range c[i].Env {
for _, c := range containers {
for _, e := range c.Env {
assert.Equal(t, "XXXXXX", e.Value)
}
}
Expand Down

0 comments on commit 7f9f6d3

Please sign in to comment.