Repository: aquasecurity/kube-bench (go)

Issue:
cfg/cis-1.6's 4.2.1 get a false negative result
**Overview**
if kubelet run only with cmd parameter `--anonymous-auth=false` and cannot find configuration file in server, cis-1.6-4.2.1 rule will get a false negative result

**How did you run kube-bench?**
```bash
kube-bench run --benchmark=cis-1.6 --targets node --check=4.2.1
```

**What happened?**
```bash
/root/kube-bench-main/executables-rzdMAHOz82/___224_worker run --benchmark=cis-1.6 --targets node --check=4.2.1 -v=3
....
I0811 17:31:40.822903   34122 check.go:110] -----   Running check 4.2.1   -----
I0811 17:31:40.882694   34122 check.go:299] Command: "/bin/ps -fC kubelet"
I0811 17:31:40.882733   34122 check.go:300] Output:
 "UID        PID  PPID  C STIME TTY          TIME CMD\nroot     48387 48366 19 Aug06 ?        1-02:13:21 kubelet --anonymous-auth=false --network-plugin=cni --registry-burst=10 ....
I0811 17:31:40.886387   34122 check.go:180] failed to run: "/bin/cat /var/lib/kubelet/config.yaml", output: "/bin/cat: /var/lib/kubelet/config.yaml: No such file or directory\n", error: exit status 1
I0811 17:31:40.886411   34122 check.go:186] Command: "/bin/cat /var/lib/kubelet/config.yaml" TestResult: <<EMPTY>> 
I0811 17:31:40.886424   34122 check.go:190] failed to run: "/bin/cat /var/lib/kubelet/config.yaml", output: "/bin/cat: /var/lib/kubelet/config.yaml: No such file or directory\n", error: exit status 1
[INFO] 4 Worker Node Security Configuration
[INFO] 4.2 Kubelet
[FAIL] 4.2.1 Ensure that the anonymous-auth argument is set to false (Automated)
```

**What did you expect to happen:**
[PASS] 4.2.1 Ensure that the anonymous-auth argument is set to false (Automated)

**Environment** 

[What is your version of kube-bench? (run `kube-bench version`)]
build from the latest source code

**Reason**
https://github.com/aquasecurity/kube-bench/blob/main/check/check.go#L195-L212
if it cannot find configuration file, `err` will not be `nil`, so let the false negative result
```go
c.AuditConfigOutput, err = runAudit(c.AuditConfig)
```

Any advice for this issue? Thanks ~

Pull request:
bugfix: false negative when audit_config is defined along with audit …
…and config file not found

Suppress the file not found error only when we have audit or auditEnv is defined and they have valid output captured. As, we already have output from audit command. So we can proceed for our tests even though we didnt find config file. 
file not found error: `failed to run: "/test/config.yaml", output: "/bin/sh: line 1: /test/config.yaml: No such file or directory\n", error: exit status 127`

resolve: #1364 
resolve #1242

Patch:
diff --git a/check/check.go b/check/check.go
index 06fac05..cec1079 100644
--- a/check/check.go
+++ b/check/check.go
@@ -208,6 +208,14 @@ func (c *Check) runAuditCommands() (lastCommand string, err error) {
 	}
 
 	c.AuditConfigOutput, err = runAudit(c.AuditConfig)
+	// when file not found then error comes as exit status 127
+	if err != nil && strings.Contains(err.Error(), "exit status 127") &&
+		(c.AuditEnvOutput != "" || c.AuditOutput != "") {
+		// suppress file not found error when there is Audit OR auditEnv output present
+		glog.V(3).Info(err)
+		err = nil
+		c.AuditConfigOutput = ""
+	}
 	return c.AuditConfig, err
 }
 
@@ -227,8 +235,8 @@ func (c *Check) execute() (finalOutput *testOutput, err error) {
 		t.auditUsed = AuditCommand
 		result := *(t.execute(c.AuditOutput))
 
-		// Check for AuditConfigOutput only if AuditConfig is set
-		if !result.flagFound && c.AuditConfig != "" {
+		// Check for AuditConfigOutput only if AuditConfig is set and auditConfigOutput is not empty
+		if !result.flagFound && c.AuditConfig != "" && c.AuditConfigOutput != "" {
 			// t.isConfigSetting = true
 			t.auditUsed = AuditConfig
 			result = *(t.execute(c.AuditConfigOutput))


Test patch:
diff --git a/check/check_test.go b/check/check_test.go
index 79eb046..124e6f9 100644
--- a/check/check_test.go
+++ b/check/check_test.go
@@ -69,6 +69,31 @@ func TestCheck_Run(t *testing.T) {
 			},
 			Expected: PASS,
 		},
+		{
+			name: "Scored checks that pass should PASS when config file is not present",
+			check: Check{
+				Scored:      true,
+				Audit:       "echo hello",
+				AuditConfig: "/test/config.yaml",
+				Tests: &tests{TestItems: []*testItem{{
+					Flag: "hello",
+					Set:  true,
+				}}},
+			},
+			Expected: PASS,
+		},
+		{
+			name: "Scored checks that pass should FAIL when config file is not present",
+			check: Check{
+				Scored:      true,
+				AuditConfig: "/test/config.yaml",
+				Tests: &tests{TestItems: []*testItem{{
+					Flag: "hello",
+					Set:  true,
+				}}},
+			},
+			Expected: FAIL,
+		},
 	}
 
 	for _, testCase := range testCases {