1
0
mirror of https://github.com/aquasecurity/kube-bench.git synced 2024-11-25 17:38:21 +00:00

Expected result pattern not always shows (#784)

* Add expectedResultPattern to invalid test

when testing and try convert to numeric we didn't set expectedResultPattern value.

* check for auditconfig before using it

The current state is that when ever audit output is not what we search for we check for auditConfig output which is sometime empty and therefore create empty expected result as described in #694

* Fix issue about expectedResultPattern

expectedResultPattern not always shown and wasn't accurate enough 
Issue #705

* Add tests for ExpectedResult and fixes

Add tests for ExpectedResult with the new output and the verify that the fix is working

* Add missing flags

In some cases not having audit or audit_config flag would fail the test.
So added just a simple commands like echo something to solve this issue 
Also add bitmask checks

* Add example IAM policy

* Pass RotateKubeletServerCertificate related checks if it's not found (#767)

* Allow for environment variables to be checked in tests (#755)

* Initial commit for checking environment variables for etcd

* Revert config changes

* Remove redundant struct data

* Fix issues with failing tests

* Initial changes based on code review

* Add option to disable envTesting + Update docs

* Initial tests

* Finished testing

* Fix broken tests

* Add a total summary and always show all tests. (#759)

Whether the total summary is shown can be specified with an option.

Fixes #528

Signed-off-by: Christian Zunker <christian.zunker@codecentric.cloud>

* Update Readme.md file with link to Contribution guide (#754)

* Update License with the year and the owner name

Please add this to make your license agreement strong

* Updated Readme.md file with license and proper documentation links

I have added a proper license agreement to the documentation. Also shortened the links to the issues so that it does not break in any on the forks.

* Update LICENSE

* Update README.md

* Update README.md

* Remove erroneous license info

Co-authored-by: Liz Rice <liz@lizrice.com>

* Support auto-detect platform when running on EKS or GKE (#683)

* Support auto-detect platform when running on EKS or GKE

* Change to get platform name from `kubectl version`

* fix regexp and add test

* Update Server Version match for EKS

* try to get version info from api sever at first

* Change expected expectedResultPattern

Now expectedResultPattern is more verbose

* Update ops tests

* Fix unit tests

* Fix bitmask output syntax

* Changes to be committed:
	modified:   check/check.go
	modified:   check/test.go
	modified:   check/test_test.go
fix unit testing and test.go to resolve conflicts.

* Change found to flagFound

* add missing }

* change found to flag found

Co-authored-by: yoavrotems <yoavrotems97@gmail.com>
This commit is contained in:
Liz Rice 2020-12-24 14:38:22 +00:00 committed by GitHub
parent b6f619cdcb
commit 6452df7c7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 707 additions and 403 deletions

View File

@ -220,14 +220,22 @@ func (c *Check) execute() (finalOutput *testOutput, err error) {
// Try with the auditOutput first, and if that's not found, try the auditConfigOutput // Try with the auditOutput first, and if that's not found, try the auditConfigOutput
t.auditUsed = AuditCommand t.auditUsed = AuditCommand
result := *(t.execute(c.AuditOutput)) result := *(t.execute(c.AuditOutput))
if !result.found {
// Check for AuditConfigOutput only if AuditConfig is set
if !result.flagFound && c.AuditConfig != "" {
//t.isConfigSetting = true
t.auditUsed = AuditConfig t.auditUsed = AuditConfig
result = *(t.execute(c.AuditConfigOutput)) result = *(t.execute(c.AuditConfigOutput))
if !result.found && t.Env != "" { if !result.flagFound && t.Env != "" {
t.auditUsed = AuditEnv t.auditUsed = AuditEnv
result = *(t.execute(c.AuditEnvOutput)) result = *(t.execute(c.AuditEnvOutput))
} }
} }
if !result.flagFound && t.Env != "" {
t.auditUsed = AuditEnv
result = *(t.execute(c.AuditEnvOutput))
}
res[i] = result res[i] = result
expectedResultArr[i] = res[i].ExpectedResult expectedResultArr[i] = res[i].ExpectedResult
} }

View File

@ -1,14 +1,15 @@
--- ---
controls: controls:
id: 1 id: 1
text: "Master Checks" text: "Test Checks"
type: "master" type: "master"
groups: groups:
- id: 1.1 - id: 1.1
text: "Kube-apiserver" text: "First Group"
checks: checks:
- id: 0 - id: 0
text: "flag is set" text: "flag is set"
audit: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- flag: "--allow-privileged" - flag: "--allow-privileged"
@ -16,6 +17,7 @@ groups:
- id: 1 - id: 1
text: "flag is not set" text: "flag is not set"
audit: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- flag: "--basic-auth" - flag: "--basic-auth"
@ -23,6 +25,7 @@ groups:
- id: 2 - id: 2
text: "flag value is set to some value" text: "flag value is set to some value"
audit: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- flag: "--insecure-port" - flag: "--insecure-port"
@ -33,6 +36,7 @@ groups:
- id: 3 - id: 3
text: "flag value is greater than or equal some number" text: "flag value is greater than or equal some number"
audit: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- flag: "--audit-log-maxage" - flag: "--audit-log-maxage"
@ -43,6 +47,7 @@ groups:
- id: 4 - id: 4
text: "flag value is less than some number" text: "flag value is less than some number"
audit: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- flag: "--max-backlog" - flag: "--max-backlog"
@ -53,6 +58,7 @@ groups:
- id: 5 - id: 5
text: "flag value does not have some value" text: "flag value does not have some value"
audit: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- flag: "--admission-control" - flag: "--admission-control"
@ -63,6 +69,7 @@ groups:
- id: 6 - id: 6
text: "test AND binary operation" text: "test AND binary operation"
audit: "echo \"Non empty command\""
tests: tests:
bin_op: and bin_op: and
test_items: test_items:
@ -73,6 +80,7 @@ groups:
- id: 7 - id: 7
text: "test OR binary operation" text: "test OR binary operation"
audit: "echo \"Non empty command\""
tests: tests:
bin_op: or bin_op: or
test_items: test_items:
@ -87,38 +95,29 @@ groups:
- id: 8 - id: 8
text: "test flag with arbitrary text" text: "test flag with arbitrary text"
audit: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- flag: "644" - flag: "permissions"
compare: compare:
op: eq op: eq
value: "644" value: "SomeValue"
set: true set: true
- id: 9 - id: 9
text: "test permissions" text: "test permissions"
audit: "/bin/sh -c 'if test -e $config; then stat -c %a $config; fi'" audit: "/bin/sh -c 'if test -e $config; then stat -c permissions=%a $config; fi'"
tests: tests:
bin_op: or
test_items: test_items:
- flag: "644" - flag: "permissions"
compare: compare:
op: eq op: bitmask
value: "644" value: "644"
set: true set: true
- flag: "640"
compare:
op: eq
value: "640"
set: true
- flag: "600"
compare:
op: eq
value: "600"
set: true
- id: 10 - id: 10
text: "flag value includes some value in a comma-separated list, value is last in list" text: "flag value includes some value in a comma-separated list, value is last in list"
audit: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- flag: "--admission-control" - flag: "--admission-control"
@ -129,6 +128,7 @@ groups:
- id: 11 - id: 11
text: "flag value includes some value in a comma-separated list, value is first in list" text: "flag value includes some value in a comma-separated list, value is first in list"
audit: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- flag: "--admission-control" - flag: "--admission-control"
@ -139,6 +139,7 @@ groups:
- id: 12 - id: 12
text: "flag value includes some value in a comma-separated list, value middle of list" text: "flag value includes some value in a comma-separated list, value middle of list"
audit: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- flag: "--admission-control" - flag: "--admission-control"
@ -149,6 +150,7 @@ groups:
- id: 13 - id: 13
text: "flag value includes some value in a comma-separated list, value only one in list" text: "flag value includes some value in a comma-separated list, value only one in list"
audit: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- flag: "--admission-control" - flag: "--admission-control"
@ -159,6 +161,7 @@ groups:
- id: 14 - id: 14
text: "check that flag some-arg is set to some-val with ':' separator" text: "check that flag some-arg is set to some-val with ':' separator"
audit: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- flag: "some-arg" - flag: "some-arg"
@ -169,7 +172,10 @@ groups:
- id: 15 - id: 15
text: "jsonpath correct value on field" text: "jsonpath correct value on field"
audit: "echo \"Non empty command\""
audit_config: "echo \"Non empty command\""
tests: tests:
bin_op: or
test_items: test_items:
- path: "{.readOnlyPort}" - path: "{.readOnlyPort}"
compare: compare:
@ -189,6 +195,8 @@ groups:
- id: 16 - id: 16
text: "jsonpath correct case-sensitive value on string field" text: "jsonpath correct case-sensitive value on string field"
audit: "echo \"Non empty command\""
audit_config: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- path: "{.stringValue}" - path: "{.stringValue}"
@ -209,6 +217,8 @@ groups:
- id: 17 - id: 17
text: "jsonpath correct value on boolean field" text: "jsonpath correct value on boolean field"
audit: "echo \"Non empty command\""
audit_config: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- path: "{.trueValue}" - path: "{.trueValue}"
@ -229,6 +239,8 @@ groups:
- id: 18 - id: 18
text: "jsonpath field absent" text: "jsonpath field absent"
audit: "echo \"Non empty command\""
audit_config: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- path: "{.notARealField}" - path: "{.notARealField}"
@ -236,6 +248,8 @@ groups:
- id: 19 - id: 19
text: "jsonpath correct value on nested field" text: "jsonpath correct value on nested field"
audit: "echo \"Non empty command\""
audit_config: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- path: "{.authentication.anonymous.enabled}" - path: "{.authentication.anonymous.enabled}"
@ -246,6 +260,8 @@ groups:
- id: 20 - id: 20
text: "yamlpath correct value on field" text: "yamlpath correct value on field"
audit: "echo \"Non empty command\""
audit_config: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- path: "{.readOnlyPort}" - path: "{.readOnlyPort}"
@ -256,6 +272,8 @@ groups:
- id: 21 - id: 21
text: "yamlpath field absent" text: "yamlpath field absent"
audit: "echo \"Non empty command\""
audit_config: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- path: "{.fieldThatIsUnset}" - path: "{.fieldThatIsUnset}"
@ -263,6 +281,8 @@ groups:
- id: 22 - id: 22
text: "yamlpath correct value on nested field" text: "yamlpath correct value on nested field"
audit: "echo \"Non empty command\""
audit_config: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- path: "{.authentication.anonymous.enabled}" - path: "{.authentication.anonymous.enabled}"
@ -273,6 +293,8 @@ groups:
- id: 23 - id: 23
text: "path on invalid json" text: "path on invalid json"
audit: "echo \"Non empty command\""
audit_config: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- path: "{.authentication.anonymous.enabled}" - path: "{.authentication.anonymous.enabled}"
@ -283,13 +305,16 @@ groups:
- id: 24 - id: 24
text: "path with broken expression" text: "path with broken expression"
audit: "echo \"Non empty command\""
audit_config: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- path: "{.missingClosingBrace" - path: "{.missingClosingBrace}"
set: true set: true
- id: 25 - id: 25
text: "yamlpath on invalid yaml" text: "yamlpath on invalid yaml"
audit: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- path: "{.authentication.anonymous.enabled}" - path: "{.authentication.anonymous.enabled}"
@ -300,6 +325,8 @@ groups:
- id: 26 - id: 26
text: "check regex op matches" text: "check regex op matches"
audit: "echo \"Non empty command\""
audit_config: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- path: "{.currentMasterVersion}" - path: "{.currentMasterVersion}"
@ -310,6 +337,7 @@ groups:
- id: 27 - id: 27
text: "check boolean flag with no value" text: "check boolean flag with no value"
audit: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- flag: "--peer-client-cert-auth" - flag: "--peer-client-cert-auth"
@ -320,6 +348,7 @@ groups:
- id: 28 - id: 28
text: "check boolean flag with false value" text: "check boolean flag with false value"
audit: "echo \"Non empty command\""
tests: tests:
test_items: test_items:
- flag: "--peer-client-cert-auth" - flag: "--peer-client-cert-auth"
@ -587,7 +616,7 @@ groups:
path: '{.readOnlyPort}' path: '{.readOnlyPort}'
set: false set: false
scored: true scored: true
- id: 15 - id: 16
text: "parameter and config file don't have same default - parameter has bad value and config is not present - failing" text: "parameter and config file don't have same default - parameter has bad value and config is not present - failing"
audit: "echo '--read-only-port=1'" audit: "echo '--read-only-port=1'"
audit_config: "echo ''" audit_config: "echo ''"

View File

@ -79,7 +79,7 @@ type compare struct {
type testOutput struct { type testOutput struct {
testResult bool testResult bool
found bool flagFound bool
actualResult string actualResult string
ExpectedResult string ExpectedResult string
} }
@ -221,7 +221,7 @@ func (t testItem) evaluate(s string) *testOutput {
if t.Set { if t.Set {
if match && t.Compare.Op != "" { if match && t.Compare.Op != "" {
result.ExpectedResult, result.testResult = compareOp(t.Compare.Op, value, t.Compare.Value) result.ExpectedResult, result.testResult = compareOp(t.Compare.Op, value, t.Compare.Value, t.value())
} else { } else {
result.ExpectedResult = fmt.Sprintf("'%s' is present", t.value()) result.ExpectedResult = fmt.Sprintf("'%s' is present", t.value())
result.testResult = match result.testResult = match
@ -231,13 +231,14 @@ func (t testItem) evaluate(s string) *testOutput {
result.testResult = !match result.testResult = !match
} }
result.found = match result.flagFound = match
glog.V(3).Info(fmt.Sprintf("found %v", result.found)) glog.V(3).Info(fmt.Sprintf("found %v", result.flagFound))
return result return result
} }
func compareOp(tCompareOp string, flagVal string, tCompareValue string) (string, bool) { func compareOp(tCompareOp string, flagVal string, tCompareValue string, flagName string) (string, bool) {
expectedResultPattern := "" expectedResultPattern := ""
testResult := false testResult := false
@ -266,24 +267,25 @@ func compareOp(tCompareOp string, flagVal string, tCompareValue string) (string,
case "gt", "gte", "lt", "lte": case "gt", "gte", "lt", "lte":
a, b, err := toNumeric(flagVal, tCompareValue) a, b, err := toNumeric(flagVal, tCompareValue)
if err != nil { if err != nil {
expectedResultPattern = "Invalid Number(s) used for comparison: '%s' '%s'"
glog.V(1).Infof(fmt.Sprintf("Not numeric value - flag: %q - compareValue: %q %v\n", flagVal, tCompareValue, err)) glog.V(1).Infof(fmt.Sprintf("Not numeric value - flag: %q - compareValue: %q %v\n", flagVal, tCompareValue, err))
return "Invalid Number(s) used for comparison", false return fmt.Sprintf(expectedResultPattern, flagVal, tCompareValue), false
} }
switch tCompareOp { switch tCompareOp {
case "gt": case "gt":
expectedResultPattern = "%s is greater than %s" expectedResultPattern = "'%s' is greater than %s"
testResult = a > b testResult = a > b
case "gte": case "gte":
expectedResultPattern = "%s is greater or equal to %s" expectedResultPattern = "'%s' is greater or equal to %s"
testResult = a >= b testResult = a >= b
case "lt": case "lt":
expectedResultPattern = "%s is lower than %s" expectedResultPattern = "'%s' is lower than %s"
testResult = a < b testResult = a < b
case "lte": case "lte":
expectedResultPattern = "%s is lower or equal to %s" expectedResultPattern = "'%s' is lower or equal to %s"
testResult = a <= b testResult = a <= b
} }
@ -292,11 +294,11 @@ func compareOp(tCompareOp string, flagVal string, tCompareValue string) (string,
testResult = strings.Contains(flagVal, tCompareValue) testResult = strings.Contains(flagVal, tCompareValue)
case "nothave": case "nothave":
expectedResultPattern = " '%s' not have '%s'" expectedResultPattern = "'%s' does not have '%s'"
testResult = !strings.Contains(flagVal, tCompareValue) testResult = !strings.Contains(flagVal, tCompareValue)
case "regex": case "regex":
expectedResultPattern = " '%s' matched by '%s'" expectedResultPattern = "'%s' matched by regex expression '%s'"
opRe := regexp.MustCompile(tCompareValue) opRe := regexp.MustCompile(tCompareValue)
testResult = opRe.MatchString(flagVal) testResult = opRe.MatchString(flagVal)
@ -307,7 +309,7 @@ func compareOp(tCompareOp string, flagVal string, tCompareValue string) (string,
testResult = allElementsValid(s, target) testResult = allElementsValid(s, target)
case "bitmask": case "bitmask":
expectedResultPattern = "bitmask '%s' AND '%s'" expectedResultPattern = "%s has permissions " + flagVal + ", expected %s or more restrictive"
requested, err := strconv.ParseInt(flagVal, 8, 64) requested, err := strconv.ParseInt(flagVal, 8, 64)
if err != nil { if err != nil {
glog.V(1).Infof(fmt.Sprintf("Not numeric value - flag: %q - compareValue: %q %v\n", flagVal, tCompareValue, err)) glog.V(1).Infof(fmt.Sprintf("Not numeric value - flag: %q - compareValue: %q %v\n", flagVal, tCompareValue, err))
@ -324,7 +326,7 @@ func compareOp(tCompareOp string, flagVal string, tCompareValue string) (string,
return expectedResultPattern, testResult return expectedResultPattern, testResult
} }
return fmt.Sprintf(expectedResultPattern, flagVal, tCompareValue), testResult return fmt.Sprintf(expectedResultPattern, flagName, tCompareValue), testResult
} }
func unmarshal(s string, jsonInterface *interface{}) error { func unmarshal(s string, jsonInterface *interface{}) error {

File diff suppressed because it is too large Load Diff