Sensitive information in source code - Ruby

Sensitive information in source code - Ruby

Need

Protection of sensitive information in source code

Context

  • Usage of Ruby 2.0+ for developing Ruby applications
  • Usage of aws-sdk for interacting with Amazon Web Services (AWS) services

Description

Non compliant code

        # config/initializers/aws.rb
Aws.config.update({
  region: 'us-west-2',
  credentials: Aws::Credentials.new('my_access_key_id', 'my_secret_access_key')
})
        
        

The above code is a Ruby on Rails initializer file that is used to setup the AWS SDK. The AWS SDK is being configured with access keys that are hardcoded directly into the source code.

This is a security vulnerability because anyone who has access to this source code will also have access to these AWS access keys. If these keys were to fall into the wrong hands, they could be used to gain access to all resources in your AWS account, leading to potential data loss, unauthorized access to sensitive data, and large unexpected costs.

Moreover, these keys are not encrypted, which means they are stored in plain text. This makes it even easier for an attacker to use these keys if they were to gain access to them. This is a clear violation of the principle of least privilege, which states that code should only have the minimum permissions required to perform its function.

Additionally, storing sensitive information in the source code repository is a bad practice. It makes it difficult to manage and rotate secrets, and it increases the likelihood of secrets being leaked. It also makes it difficult to manage different configurations for different environments (e.g., development, staging, production), as each environment should have its own set of secrets.

Steps

  • Remove sensitive information from the source code
  • Store sensitive information in a secure location outside of the source code repository
  • Use environment variables or a configuration file to store and retrieve sensitive information
  • Encrypt sensitive information before storing it
  • Implement access controls and permissions to restrict access to sensitive information
  • Regularly review and audit the source code repository for any accidental inclusion of sensitive information

Compliant code

        # config/initializers/aws.rb
Aws.config.update({
  region: 'us-west-2',
  credentials: Aws::Credentials.new(ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'])
})
        
        

The original code contained hard-coded AWS credentials, which is a security vulnerability as it exposes sensitive information in the source code. This can lead to unauthorized access if the code is ever exposed or pushed to a public repository.

The updated code replaces the hard-coded credentials with environment variables. This is a more secure practice as the actual values of the AWS credentials are not exposed in the source code. Instead, they are stored in the environment of the server where the application is running.

The environment variables 'AWS_ACCESS_KEY_ID' and 'AWS_SECRET_ACCESS_KEY' should be set in the server environment where the application is running. This can be done in various ways depending on the server setup. For example, in a Unix-based system, these can be set in the .bashrc or .bash_profile file.

This change ensures that even if the source code is exposed, the AWS credentials remain secure. Furthermore, using environment variables allows for easier management and rotation of credentials, as the code does not need to be updated when credentials are changed
- only the environment variables need to be updated.

Remember to never store sensitive information such as usernames, passwords, or API keys directly in your source code. Always use secure methods such as environment variables or encrypted configuration files. Regularly review and audit your source code to ensure no sensitive information is accidentally included.

References