Skip to main content

Sensitive information in source code

Need

Protection of sensitive information in source code

Context

  • Usage of Scala for building scalable and high-performance applications

Description

Non compliant code

package utils

object Config {
val dbUsername = "admin"
val dbPassword = "password123"
val awsSecretKey = "test"
val adminEmail = "[email protected]"
val serverIp = "192.168.1.1"
}

This Scala code snippet is an example of a vulnerable practice in handling sensitive information. The Config object is storing sensitive information such as a database username and password, an AWS secret key, an admin email, and a server IP address.

The problem with this approach is that the sensitive data is stored in plain text directly in the source code. This is a bad practice because:

  1. Exposure of sensitive data: If the source code is ever exposed or shared, the sensitive data will be exposed as well. This could lead to unauthorized access to the resources these credentials protect.

  2. Lack of encryption: The sensitive data is not encrypted, making it easy for anyone who has access to the source code to read and misuse the data.

  3. Version control issues: Storing sensitive data in the source code means that the data will be included in the version control system (like Git). This means that even if the sensitive data is removed from the latest version of the code, it will still exist in the version control history.

  4. Inflexibility: Hard-coding credentials into the source code makes it difficult to change them without changing the code and redeploying the application. It also makes it impossible to use different credentials for different environments (e.g. development, testing, production).

To fix this vulnerability, sensitive data should be removed from the source code and instead be securely managed using environment variables, encrypted configuration files, or dedicated secret management systems.

Steps

  • Remove sensitive information from the source code
  • Store sensitive information in a secure location
  • Use environment variables or configuration files to store sensitive information
  • Encrypt sensitive information before storing it
  • Implement access controls to restrict access to sensitive information
  • Regularly review and update sensitive information to ensure it remains secure

Compliant code

package utils

import com.typesafe.config.ConfigFactory

object Config {
private val config = ConfigFactory.load()

val dbUsername: String = config.getString("db.username")
val dbPassword: String = config.getString("db.password")
val awsSecretKey: String = config.getString("aws.secretKey")
val adminEmail: String = config.getString("admin.email")
val serverIp: String = config.getString("server.ip")
}

The updated code no longer contains sensitive information directly in the source code. Instead, it uses the Typesafe Config library to load these values from a configuration file. This configuration file should be stored securely and not included in the source code repository.

The ConfigFactory.load() method loads configuration in the following order:

  1. System properties
  2. Application properties: application.conf, application.json, application.properties
  3. Default configuration: reference.conf

This allows you to override configuration values with system properties, which can be useful for setting sensitive data like passwords or secret keys in a production environment.

Here is an example of what the application.conf file might look like:

db {
username = "admin"
password = "password123"
}

aws {
secretKey = "test"
}

admin {
email = "[email protected]"
}

server {
ip = "192.168.1.1"
}

Remember to never commit sensitive data to your source code repository. Instead, use environment variables or a secure configuration management system to set these values in your production environment.

Also, consider encrypting sensitive data and implementing access controls to further enhance the security of your application. Regularly review and update your security practices to ensure they remain effective against new threats.

References