Skip to content

Commit ebb49a5

Browse files
authored
Merge pull request #787 from yuumasato/drop-scanning-privileges
CMP-3722: Do not use privileged container to scan the node
2 parents 5c45de9 + 3c37eae commit ebb49a5

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

pkg/controller/compliancescan/scan.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,13 @@ func newScanPodForNode(scanInstance *compv1alpha1.ComplianceScan, node *corev1.N
219219
Image: utils.GetComponentImage(utils.OPENSCAP),
220220
Command: []string{OpenScapScriptPath},
221221
SecurityContext: &corev1.SecurityContext{
222-
Privileged: &trueVal,
223-
ReadOnlyRootFilesystem: &trueP,
222+
Privileged: &falseP,
223+
AllowPrivilegeEscalation: &falseP,
224+
ReadOnlyRootFilesystem: &trueP,
225+
Capabilities: &corev1.Capabilities{
226+
Drop: []corev1.Capability{"ALL"},
227+
Add: []corev1.Capability{"CAP_SYS_CHROOT"},
228+
},
224229
// TODO(jaosorior): Figure out if the default
225230
// seccomp profile is sufficient here.
226231
},

tests/e2e/parallel/main_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,62 @@ func TestSingleScanSucceeds(t *testing.T) {
573573
}
574574
defer f.Client.Delete(context.TODO(), testScan)
575575

576+
// Verify scanner container security capabilities during running phase
577+
err = f.WaitForScanStatus(f.OperatorNamespace, scanName, compv1alpha1.PhaseRunning)
578+
if err != nil {
579+
t.Fatal(err)
580+
}
581+
582+
// Assert scanner container has correct capabilities (drops all, only has CAP_SYS_CHROOT)
583+
pods, err := f.GetPodsForScan(scanName)
584+
if err != nil {
585+
t.Fatal(err)
586+
}
587+
if len(pods) < 1 {
588+
t.Fatal("No scanner pods found for the scan")
589+
}
590+
591+
// Find the scanner container and verify its capabilities
592+
found := false
593+
for _, pod := range pods {
594+
for _, container := range pod.Spec.Containers {
595+
if container.Name == "scanner" {
596+
found = true
597+
if container.SecurityContext == nil {
598+
t.Fatal("Scanner container has no security context")
599+
}
600+
if container.SecurityContext.Capabilities == nil {
601+
t.Fatal("Scanner container has no capabilities configuration")
602+
}
603+
604+
// Verify privileged mode is false
605+
if container.SecurityContext.Privileged != nil && *container.SecurityContext.Privileged {
606+
t.Fatal("Expected scanner container to run in non-privileged mode")
607+
}
608+
609+
// Verify all capabilities are dropped
610+
droppedCaps := container.SecurityContext.Capabilities.Drop
611+
if len(droppedCaps) != 1 || string(droppedCaps[0]) != "ALL" {
612+
t.Fatalf("Expected scanner container to drop ALL capabilities, got: %v", droppedCaps)
613+
}
614+
615+
// Verify only CAP_SYS_CHROOT is added
616+
addedCaps := container.SecurityContext.Capabilities.Add
617+
if len(addedCaps) != 1 || string(addedCaps[0]) != "CAP_SYS_CHROOT" {
618+
t.Fatalf("Expected scanner container to only have CAP_SYS_CHROOT capability, got: %v", addedCaps)
619+
}
620+
break
621+
}
622+
}
623+
if found {
624+
break
625+
}
626+
}
627+
628+
if !found {
629+
t.Fatal("Scanner container not found in any pod")
630+
}
631+
576632
err = f.WaitForScanStatus(f.OperatorNamespace, scanName, compv1alpha1.PhaseDone)
577633
if err != nil {
578634
t.Fatal(err)

0 commit comments

Comments
 (0)