Skip to content

Commit

Permalink
Merge pull request #286 from kubescape/rulefix
Browse files Browse the repository at this point in the history
r1001 and r1004 should not alert without a profile
  • Loading branch information
matthyx authored May 15, 2024
2 parents 0f432b3 + 171f55c commit a494ddf
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 10 deletions.
16 changes: 11 additions & 5 deletions pkg/ruleengine/v1/helpers.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ruleengine

import (
"errors"
"fmt"
"node-agent/pkg/objectcache"
"path/filepath"
Expand All @@ -11,6 +12,11 @@ import (
"github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1"
)

var (
ContainerNotFound = errors.New("container not found")
ProfileNotFound = errors.New("application profile not found")
)

func getExecPathFromEvent(event *tracerexectype.Event) string {
if len(event.Args) > 0 {
return event.Args[0]
Expand Down Expand Up @@ -44,7 +50,7 @@ func getContainerFromApplicationProfile(ap *v1beta1.ApplicationProfile, containe
return ap.Spec.EphemeralContainers[i], nil
}
}
return v1beta1.ApplicationProfileContainer{}, fmt.Errorf("container %s not found in application profile", containerName)
return v1beta1.ApplicationProfileContainer{}, ContainerNotFound
}

func getContainerFromNetworkNeighborhood(nn *v1beta1.NetworkNeighborhood, containerName string) (v1beta1.NetworkNeighborhoodContainer, error) {
Expand All @@ -63,7 +69,7 @@ func getContainerFromNetworkNeighborhood(nn *v1beta1.NetworkNeighborhood, contai
return nn.Spec.EphemeralContainers[i], nil
}
}
return v1beta1.NetworkNeighborhoodContainer{}, fmt.Errorf("container %s not found in network neighborhood profile", containerName)
return v1beta1.NetworkNeighborhoodContainer{}, ContainerNotFound
}

func getContainerMountPaths(namespace, podName, containerName string, k8sObjCache objectcache.K8sObjectCache) ([]string, error) {
Expand Down Expand Up @@ -100,18 +106,18 @@ func getContainerMountPaths(namespace, podName, containerName string, k8sObjCach
return mountPaths, nil
}

func isExecEventWhitelisted(execEvent *tracerexectype.Event, objectCache objectcache.ObjectCache, compareArgs bool) (bool, error) {
func isExecEventInProfile(execEvent *tracerexectype.Event, objectCache objectcache.ObjectCache, compareArgs bool) (bool, error) {
// Check if the exec is whitelisted, if so, return nil
execPath := getExecPathFromEvent(execEvent)

ap := objectCache.ApplicationProfileCache().GetApplicationProfile(execEvent.Runtime.ContainerID)
if ap == nil {
return false, fmt.Errorf("application profile not found for container %s", execEvent.Runtime.ContainerID)
return false, ProfileNotFound
}

appProfileExecList, err := getContainerFromApplicationProfile(ap, execEvent.GetContainer())
if err != nil {
return false, fmt.Errorf("container %s not found in application profile", execEvent.GetContainer())
return false, ContainerNotFound
}

for _, exec := range appProfileExecList.Execs {
Expand Down
5 changes: 4 additions & 1 deletion pkg/ruleengine/v1/r1001_exec_binary_not_in_base_image.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ruleengine

import (
"errors"
"fmt"
"node-agent/pkg/objectcache"
"node-agent/pkg/ruleengine"
Expand Down Expand Up @@ -62,7 +63,9 @@ func (rule *R1001ExecBinaryNotInBaseImage) ProcessEvent(eventType utils.EventTyp

if execEvent.UpperLayer {

if whiteListed, err := isExecEventWhitelisted(execEvent, objectCache, false); whiteListed && err != nil {
// Check if the event is expected, if so return nil
// No application profile also returns nil
if whiteListed, err := isExecEventInProfile(execEvent, objectCache, false); whiteListed || errors.Is(err, ProfileNotFound) {
return nil
}

Expand Down
6 changes: 4 additions & 2 deletions pkg/ruleengine/v1/r1004_exec_from_mount.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ruleengine

import (
"errors"
"fmt"
"node-agent/pkg/objectcache"
"node-agent/pkg/ruleengine"
Expand Down Expand Up @@ -58,8 +59,9 @@ func (rule *R1004ExecFromMount) ProcessEvent(eventType utils.EventType, event in
return nil
}

// Check if the event is whitelisted, if so return nil
if whiteListed, err := isExecEventWhitelisted(execEvent, objCache, false); whiteListed && err != nil {
// Check if the event is expected, if so return nil
// No application profile also returns nil
if whiteListed, err := isExecEventInProfile(execEvent, objCache, false); whiteListed || errors.Is(err, ProfileNotFound) {
return nil
}

Expand Down
20 changes: 18 additions & 2 deletions pkg/ruleengine/v1/r1004_exec_from_mount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

tracerexectype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/exec/types"
eventtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types"
"github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1"
corev1 "k8s.io/api/core/v1"
)

Expand All @@ -24,6 +25,7 @@ func TestR1004ExecFromMount(t *testing.T) {
ContainerName: "test",
},
},
Runtime: eventtypes.BasicRuntimeMetadata{ContainerID: "test"},
},
},
Comm: "/test",
Expand All @@ -36,8 +38,7 @@ func TestR1004ExecFromMount(t *testing.T) {
t.Errorf("Expected ruleResult to be nil since test is not from a mounted path")
}

// Test case where path is mounted

// Test case where path is mounted, but not application profile is found
e.Comm = "/var/test1/test"
objCache := RuleObjectCacheMock{}
objCache.SetPodSpec(
Expand Down Expand Up @@ -65,7 +66,22 @@ func TestR1004ExecFromMount(t *testing.T) {
},
},
)
ruleResult = r.ProcessEvent(utils.ExecveEventType, e, &RuleObjectCacheMock{})
if ruleResult != nil {
t.Errorf("Expected ruleResult to be nil since no application profile is found")
}

// Test case where path is mounted, with application profile
objCache.SetApplicationProfile(&v1beta1.ApplicationProfile{
Spec: v1beta1.ApplicationProfileSpec{
Containers: []v1beta1.ApplicationProfileContainer{
{
Name: "test",
Execs: []v1beta1.ExecCalls{{Path: "/var/other/test"}},
},
},
},
})
ruleResult = r.ProcessEvent(utils.ExecveEventType, e, &objCache)
if ruleResult == nil {
t.Errorf("Expected ruleResult since exec is from a mounted path")
Expand Down

0 comments on commit a494ddf

Please sign in to comment.