Why is this an issue?

Hard-coding secrets in source code or binaries makes it easy for attackers to extract sensitive information, especially in distributed or open-source applications. This practice exposes credentials and tokens, increasing the risk of unauthorized access and data breaches.

This rule detects variables/fields having a name matching a list of words (secret, token, credential, auth, api[_.-]?key) being assigned a pseudorandom hard-coded value. The pseudorandomness of the hard-coded value is based on its entropy and the probability to be human-readable. The randomness sensibility can be adjusted if needed. Lower values will detect less random values, raising potentially more false positives.

How to fix it

Secrets should be stored in a configuration file that is not committed to the code repository, in a database, or managed by your cloud provider’s secrets management service. If a secret is exposed in the source code, it must be rotated immediately.

Code Examples

Noncompliant code example

private val MY_SECRET = "47828a8dd77ee1eb9dde2d5e93cb221ce8c32b37"

fun main() {
  MyClass.callMyService(MY_SECRET)
}

Compliant solution

Using AWS Secrets Manager:

import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest;
import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse;

fun main() {
  SecretsManagerClient secretsClient = ...
  MyClass.doSomething(secretsClient, "MY_SERVICE_SECRET")
}

fun doSomething(secretsClient: SecretsManagerClient, secretName: String) {
  val valueRequest = GetSecretValueRequest.builder()
    .secretId(secretName)
    .build()

  val valueResponse = secretsClient.getSecretValue(valueRequest)
  val secret = valueResponse.secretString()
  // do something with the secret
  MyClass.callMyService(secret)
}

Using Azure Key Vault Secret:

import com.azure.identity.DefaultAzureCredentialBuilder;

import com.azure.security.keyvault.secrets.SecretClient;
import com.azure.security.keyvault.secrets.SecretClientBuilder;
import com.azure.security.keyvault.secrets.models.KeyVaultSecret;

fun main() {
  val keyVaultName = System.getenv("KEY_VAULT_NAME")
  val keyVaultUri = "https://$keyVaultName.vault.azure.net"

  val secretClient = SecretClientBuilder()
    .vaultUrl(keyVaultUri)
    .credential(DefaultAzureCredentialBuilder().build())
    .buildClient()

  MyClass.doSomething(secretClient, "MY_SERVICE_SECRET")
}

fun doSomething(secretClient: SecretClent, secretName: String) {
  val retrievedSecret = secretClient.getSecret(secretName)
  val secret = retrievedSecret.getValue()

  // do something with the secret
  MyClass.callMyService(secret)
}

Resources