diff --git a/rules/S6418/kotlin/metadata.json b/rules/S6418/kotlin/metadata.json new file mode 100644 index 00000000000..9cdfda323aa --- /dev/null +++ b/rules/S6418/kotlin/metadata.json @@ -0,0 +1,34 @@ +{ + "tags": [ + "cwe", + "cert" + ], + "securityStandards": { + "CERT": [ + "MSC03-J." + ], + "CWE": [ + 798 + ], + "OWASP": [ + "A2" + ], + "OWASP Top 10 2021": [ + "A7" + ], + "OWASP Mobile Top 10 2024": [ + "M1" + ], + "PCI DSS 3.2": [ + "6.5.10" + ], + "PCI DSS 4.0": [ + "6.2.4" + ], + "ASVS 4.0": [ + "2.10.4", + "3.5.2", + "6.4.1" + ] + } +} diff --git a/rules/S6418/kotlin/rule.adoc b/rules/S6418/kotlin/rule.adoc new file mode 100644 index 00000000000..aa64beacc41 --- /dev/null +++ b/rules/S6418/kotlin/rule.adoc @@ -0,0 +1,96 @@ +:detections: variables/fields +:defaultsensibility: 5 + +include::../description.adoc[] + +include::../ask-yourself.adoc[] + +include::../recommended.adoc[] + +== Sensitive Code Example + +[source,kotlin] +---- +private val MY_SECRET = "47828a8dd77ee1eb9dde2d5e93cb221ce8c32b37" + +fun main() { + MyClass.callMyService(MY_SECRET) +} +---- + +== Compliant Solution + +Using https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/secrets-manager[AWS Secrets Manager]: + +[source,kotlin] +---- +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 https://docs.microsoft.com/en-us/azure/key-vault/secrets/quick-create-java?tabs=azure-cli[Azure Key Vault Secret]: + +[source,kotlin] +---- +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) +} +---- + + +include::../see.adoc[] + +* OWASP - https://owasp.org/www-project-mobile-top-10/2023-risks/m1-improper-credential-usage.html[Mobile Top 10 2024 Category M1 - Improper Credential Usage] +* MSC - https://wiki.sei.cmu.edu/confluence/x/OjdGBQ[MSC03-J - Never hard code sensitive information] + + +ifdef::env-github,rspecator-view[] +''' +== Implementation Specification +(visible only on this page) + +include::../message.adoc[] + + +include::../parameters.adoc[] + +''' +endif::env-github,rspecator-view[]