github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/rules/kubernetes/policies/aquacommercial/configMap_with_secrets.rego (about) 1 # METADATA 2 # title: "ConfigMap with secrets" 3 # description: "Storing secrets in configMaps is unsafe" 4 # scope: package 5 # schemas: 6 # - input: schema["kubernetes"] 7 # custom: 8 # id: AVD-KSV-0109 9 # avd_id: AVD-KSV-0109 10 # severity: HIGH 11 # short_code: configMap_with_secrets 12 # recommended_action: "Remove password/secret from configMap data value" 13 # input: 14 # selector: 15 # - type: kubernetes 16 17 package builtin.kubernetes.KSV0109 18 19 import data.lib.kubernetes 20 21 # More patterns can be added here, adding more patterns may lead to performance issue 22 patterns := [ 23 "(?i)(password\\s*(=|:))", 24 "(?i)(pw\\s*(=|:))", 25 "(?i)(pass\\s*(=|:))", 26 "(?i)(pword\\s*(=|:))", 27 "(?i)(passphrase\\s*(=|:))", 28 "(?i)(passwrd\\s*(=|:))", 29 "(?i)(passwd\\s*(=|:))", 30 "(?i)(secret\\s*(=|:))", 31 "(?i)(secretkey\\s*(=|:))", 32 "(?i)(appSecret\\s*(=|:))", 33 "(?i)(clientSecret\\s*(=|:))", 34 "(?i)(aws_access_key_id\\s*(=|:))", 35 "(?i)(pswrd\\s*(=|:))", 36 "(?i)(token\\s*(=|:))", 37 "(?i)(pwd\\s*(=|:))", 38 ] 39 40 #Added patterns for detecting secrets in key 41 patternsForKey := [ 42 "(?i)(password\\s*)", 43 "(?i)(pw\\s*)", 44 "(?i)(pass\\s*)", 45 "(?i)(pword\\s*)", 46 "(?i)(passphrase\\s*)", 47 "(?i)(passwrd\\s*)", 48 "(?i)(passwd\\s*)", 49 "(?i)(secret\\s*)", 50 "(?i)(secretkey\\s*)", 51 "(?i)(appSecret\\s*)", 52 "(?i)(clientSecret\\s*)", 53 "(?i)(aws_access_key_id\\s*)", 54 "(?i)(pswrd\\s*)", 55 "(?i)(token\\s*)", 56 "(?i)(pwd\\s*)", 57 ] 58 59 # ConfigMapWithSecret gives secret key 60 # To reduce performance overhead, only matched patterns will be applied to each value for key 61 ConfigMapWithSecret[secrets] { 62 kubernetes.kind == "ConfigMap" 63 regex.match(patterns[p], kubernetes.object.data[d]) 64 65 values := split(kubernetes.object.data[d], "\n") 66 regex.match(patterns[p], values[v]) 67 secrets = configMapValue(values[v]) 68 } 69 70 # configMapValue gives secret key, splitting either by '=' or ':' 71 configMapValue(value) = secretValue { 72 secrets := split(value, ":") 73 count(secrets) > 1 74 secretValue = secrets[0] 75 } else = secretValue { 76 secrets := split(value, "=") 77 count(secrets) > 1 78 secretValue = secrets[0] 79 } 80 81 #check if key has secrets 82 ConfigMapWithSecret[secrets] { 83 kubernetes.kind == "ConfigMap" 84 values = split(kubernetes.object.data[d], "\n") 85 regex.match(patternsForKey[p], d) 86 secrets = d 87 } 88 89 # Get the secret list, 'configMapSecretList' will be reused in rule deny to avoid multiple call for pattern search 90 configMapSecretList := ConfigMapWithSecret 91 92 deny[res] { 93 count(configMapSecretList) > 0 94 msg := kubernetes.format(sprintf("%s '%s' in '%s' namespace stores secrets in key(s) or value(s) '%s'", [kubernetes.kind, kubernetes.name, kubernetes.namespace, configMapSecretList])) 95 res := result.new(msg, kubernetes.kind) 96 }