Sensitive information in source code - API Key - Ruby

Sensitive information in source code - API Key - Ruby

Need

Secure storage and management of sensitive information such as API keys

Context

  • Usage of Ruby for building dynamic and object-oriented applications
  • Usage of HTTParty for making HTTP requests in Node.js

Description

Non compliant code

        class ApplicationController < ActionController::Base
  API_KEY = '1234567890abcdef'
  
  def api_request
    response = HTTParty.get("https://api.example.com/data?api_key=#{API_KEY}")
    # process response
  end
end
        
        

The above code represents a Ruby on Rails controller with an API key stored directly in the source code as a constant. This API key is used to authenticate requests to an external API.

The vulnerability here lies in the fact that the API key is stored in plain text directly in the source code. This means that anyone who has access to the source code would also have access to the API key, which could lead to unauthorized access to the API.

Additionally, if the source code is ever exposed (e.g., through a version control system), the API key would be exposed as well. This could have serious security implications, as it could allow an attacker to perform actions on the API with the same permissions as the legitimate application.

This is a clear violation of the principle of least privilege, which states that code (and users) should have only the permissions they need to perform their function, and no more. Storing sensitive information like API keys in source code can lead to over-privileged code and users, and can increase the potential damage from a security breach.

Steps

  • Remove the API key from the source code.
  • Store the API key in a secure location, such as environment variables or a configuration file.
  • Update the code to retrieve the API key from the secure location.
  • Ensure that the secure location is properly protected and accessible only to authorized users.
  • Consider using a secrets management solution to securely store and manage the API key.
  • Regularly rotate the API key to minimize the impact of potential leaks or breaches.

Compliant code

        class ApplicationController < ActionController::Base
  def api_request
    api_key = ENV['API_KEY']
    response = HTTParty.get("https://api.example.com/data?api_key=#{api_key}")
    # process response
  end
end
        
        

The API key is no longer stored directly in the source code. Instead, it is stored in an environment variable, which is a more secure location. The ENV['API_KEY'] syntax is used to retrieve the value of the API_KEY environment variable.

Environment variables are a standard way of passing configuration settings to an application. They are not visible in the source code and can be set differently for different environments (e.g., development, testing, production), which makes them a good place to store sensitive information such as API keys.

To set the API_KEY environment variable, you can use the export command in the terminal:

                export API_KEY=your_api_key

            


This command will set the API_KEY environment variable to your_api_key. You need to replace your_api_key with your actual API key.

Please note that this command will only set the environment variable for the current session. If you close the terminal or start a new session, you will need to set the environment variable again. To set it permanently, you can add the command to your shell's startup file (e.g., ~/.bashrc or ~/.bash_profile for Bash).

Also, consider using a secrets management solution to securely store and manage the API key. Regularly rotate the API key to minimize the impact of potential leaks or breaches.

References