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  }