Non-encrypted confidential information - Keys - Dart

Non-encrypted confidential information - Keys - Dart

Need

Encryption of confidential information

Context

  • Usage of Dart 2.0 for building high-performance, cross-platform applications
  • Usage of Shelf for managing and organizing data in a Node.js application

Description

Non compliant code

        import 'package:shelf/shelf.dart' as shelf;

void main() {
  var handler = const shelf.Pipeline().addMiddleware(shelf.logRequests())
      .addHandler(_echoRequest);

  shelf.serve(handler, 'localhost', 8080);
}

shelf.Response _echoRequest(shelf.Request request) {
  var apiKey = 'my_super_secret_api_key'; // Confidential information stored in plain text
  return shelf.Response.ok('Request for "${request.url}"');
}
        
        

In the above code, we have a simple server application using the Shelf framework in Dart. The function _echoRequest handles all the incoming requests.

The vulnerability lies in the line where we have the apiKey variable. This variable is storing a very sensitive piece of information
- an API key. This key is stored in plain text, meaning it's not encrypted or hashed in any way.

Anyone who has access to the source code, either through a repository or by gaining unauthorized access to the server, can easily view this API key. Once they have this key, they can potentially use it to make requests to the API, leading to data breaches or other security issues.

This is a serious security vulnerability, as sensitive data like API keys should never be stored in plain text. Instead, they should be encrypted or hashed, and ideally stored in a secure environment variable or a dedicated secure vault.

Steps

  • Remove the hard-coded API key from the code.
  • Store the API key in an environment variable or a secure key vault.
  • Access the API key in your code through the environment variable or key vault.
  • Ensure that the environment variable or key vault is properly secured and only accessible to authorized individuals or services.

Compliant code

        import 'dart:io';
import 'package:shelf/shelf.dart' as shelf;

void main() {
  var handler = const shelf.Pipeline().addMiddleware(shelf.logRequests())
      .addHandler(_echoRequest);

  shelf.serve(handler, 'localhost', 8080);
}

shelf.Response _echoRequest(shelf.Request request) {
  var apiKey = Platform.environment['API_KEY']; // Accessing the API key from environment variable
  return shelf.Response.ok('Request for "${request.url}"');
}
        
        

The original code had a vulnerability where the API key was stored in plain text within the code. This is a security risk as it exposes the key to anyone who has access to the code, and it could potentially be leaked in version control history or logs.

The updated code fixes this vulnerability by storing the API key in an environment variable instead. The Platform.environment method is used to access the value of the environment variable named 'API_KEY'. This way, the API key is not exposed in the code and can be securely managed outside of the application.

To set the environment variable, you can use the following command in the terminal before running your Dart application:

                export API_KEY=your_api_key

            


Remember to replace your_api_key with your actual API key.

This method of storing sensitive information is more secure, but it's still not perfect. For even better security, consider using a secure key vault service, which can securely store and manage secrets like API keys, and provide them to your application as needed.

Also, ensure that the environment variable or key vault is properly secured and only accessible to authorized individuals or services.

References