mirror of
https://github.com/aquasecurity/kube-bench.git
synced 2025-01-07 06:10:55 +00:00
* issue #344: Adds support for array comparison. Every element in the source array must exist in the target array. * issue #344: Fixed typo and found if condition based on code review * adds unit tests for valid_elements comparison * removes spaces from split strings
This commit is contained in:
parent
dab5e92bb5
commit
937bfc7b2e
@ -296,9 +296,9 @@ groups:
|
|||||||
audit: "cat $kubeletconf"
|
audit: "cat $kubeletconf"
|
||||||
tests:
|
tests:
|
||||||
test_items:
|
test_items:
|
||||||
- path: "{.tlsCipherSuites}"
|
- path: "{range .tlsCipherSuites[:]}{}{','}{end}"
|
||||||
compare:
|
compare:
|
||||||
op: eq
|
op: valid_elements
|
||||||
value: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256"
|
value: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256"
|
||||||
set: true
|
set: true
|
||||||
remediation: |
|
remediation: |
|
||||||
|
@ -37,8 +37,9 @@ import (
|
|||||||
type binOp string
|
type binOp string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
and binOp = "and"
|
and binOp = "and"
|
||||||
or = "or"
|
or = "or"
|
||||||
|
defaultArraySeparator = ","
|
||||||
)
|
)
|
||||||
|
|
||||||
type testItem struct {
|
type testItem struct {
|
||||||
@ -193,6 +194,13 @@ func compareOp(tCompareOp string, flagVal string, tCompareValue string) (string,
|
|||||||
expectedResultPattern = " '%s' matched by '%s'"
|
expectedResultPattern = " '%s' matched by '%s'"
|
||||||
opRe := regexp.MustCompile(tCompareValue)
|
opRe := regexp.MustCompile(tCompareValue)
|
||||||
testResult = opRe.MatchString(flagVal)
|
testResult = opRe.MatchString(flagVal)
|
||||||
|
|
||||||
|
case "valid_elements":
|
||||||
|
expectedResultPattern = "'%s' contains valid elements from '%s'"
|
||||||
|
s := splitAndRemoveLastSeparator(flagVal, defaultArraySeparator)
|
||||||
|
target := splitAndRemoveLastSeparator(tCompareValue, defaultArraySeparator)
|
||||||
|
testResult = allElementsValid(s, target)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if expectedResultPattern == "" {
|
if expectedResultPattern == "" {
|
||||||
@ -231,6 +239,50 @@ func executeJSONPath(path string, jsonInterface interface{}) (string, error) {
|
|||||||
return jsonpathResult, nil
|
return jsonpathResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func allElementsValid(s, t []string) bool {
|
||||||
|
sourceEmpty := s == nil || len(s) == 0
|
||||||
|
targetEmpty := t == nil || len(t) == 0
|
||||||
|
|
||||||
|
if sourceEmpty && targetEmpty {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// XOR comparison -
|
||||||
|
// if either value is empty and the other is not empty,
|
||||||
|
// not all elements are valid
|
||||||
|
if (sourceEmpty || targetEmpty) && !(sourceEmpty && targetEmpty) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sv := range s {
|
||||||
|
found := false
|
||||||
|
for _, tv := range t {
|
||||||
|
if sv == tv {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func splitAndRemoveLastSeparator(s, sep string) []string {
|
||||||
|
cleanS := strings.TrimRight(strings.TrimSpace(s), sep)
|
||||||
|
if len(cleanS) == 0 {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
ts := strings.Split(cleanS, sep)
|
||||||
|
for i := range ts {
|
||||||
|
ts[i] = strings.TrimSpace(ts[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return ts
|
||||||
|
}
|
||||||
|
|
||||||
type tests struct {
|
type tests struct {
|
||||||
TestItems []*testItem `yaml:"test_items"`
|
TestItems []*testItem `yaml:"test_items"`
|
||||||
BinOp binOp `yaml:"bin_op"`
|
BinOp binOp `yaml:"bin_op"`
|
||||||
|
@ -323,6 +323,108 @@ func TestExecuteJSONPath(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAllElementsValid(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
source []string
|
||||||
|
target []string
|
||||||
|
valid bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
source: []string{},
|
||||||
|
target: []string{},
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: []string{"blah"},
|
||||||
|
target: []string{},
|
||||||
|
valid: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: []string{},
|
||||||
|
target: []string{"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
||||||
|
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
||||||
|
"TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256"},
|
||||||
|
valid: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: []string{"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"},
|
||||||
|
target: []string{"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
||||||
|
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
||||||
|
"TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256"},
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: []string{"blah"},
|
||||||
|
target: []string{"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
||||||
|
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
||||||
|
"TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256"},
|
||||||
|
valid: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: []string{"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "blah"},
|
||||||
|
target: []string{"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
||||||
|
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
||||||
|
"TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256"},
|
||||||
|
valid: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
if !allElementsValid(c.source, c.target) && c.valid {
|
||||||
|
t.Errorf("Not All Elements in %q are found in %q \n", c.source, c.target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSplitAndRemoveLastSeparator(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
source string
|
||||||
|
valid bool
|
||||||
|
elementCnt int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
source: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
|
valid: true,
|
||||||
|
elementCnt: 8,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,",
|
||||||
|
valid: true,
|
||||||
|
elementCnt: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,",
|
||||||
|
valid: true,
|
||||||
|
elementCnt: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, ",
|
||||||
|
valid: true,
|
||||||
|
elementCnt: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: " TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,",
|
||||||
|
valid: true,
|
||||||
|
elementCnt: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
as := splitAndRemoveLastSeparator(c.source, defaultArraySeparator)
|
||||||
|
if len(as) == 0 && c.valid {
|
||||||
|
t.Errorf("Split did not work with %q \n", c.source)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.elementCnt != len(as) {
|
||||||
|
t.Errorf("Split did not work with %q expected: %d got: %d\n", c.source, c.elementCnt, len(as))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCompareOp(t *testing.T) {
|
func TestCompareOp(t *testing.T) {
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
label string
|
label string
|
||||||
@ -527,6 +629,19 @@ func TestCompareOp(t *testing.T) {
|
|||||||
{label: "op=gt, flagVal=empty", op: "regex", flagVal: "",
|
{label: "op=gt, flagVal=empty", op: "regex", flagVal: "",
|
||||||
compareValue: "blah", expectedResultPattern: " '' matched by 'blah'",
|
compareValue: "blah", expectedResultPattern: " '' matched by 'blah'",
|
||||||
testResult: false},
|
testResult: false},
|
||||||
|
|
||||||
|
// Test Op "valid_elements"
|
||||||
|
{label: "op=valid_elements, valid_elements both empty", op: "valid_elements", flagVal: "",
|
||||||
|
compareValue: "", expectedResultPattern: "'' contains valid elements from ''",
|
||||||
|
testResult: true},
|
||||||
|
|
||||||
|
{label: "op=valid_elements, valid_elements flagVal empty", op: "valid_elements", flagVal: "",
|
||||||
|
compareValue: "a,b", expectedResultPattern: "'' contains valid elements from 'a,b'",
|
||||||
|
testResult: false},
|
||||||
|
|
||||||
|
{label: "op=valid_elements, valid_elements expectedResultPattern empty", op: "valid_elements", flagVal: "a,b",
|
||||||
|
compareValue: "", expectedResultPattern: "'a,b' contains valid elements from ''",
|
||||||
|
testResult: false},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
|
Loading…
Reference in New Issue
Block a user