Sensitive information in source code - Credentials - Dart

Sensitive information in source code - Credentials - Dart

Need

Protection of sensitive information in source code

Context

  • Usage of Dart for building cross-platform mobile, web, and desktop applications
  • Usage of Shelf for managing data persistence and querying in Node.js applications

Description

Non compliant code

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

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

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

shelf.Response _echoRequest(shelf.Request request) {
  return shelf.Response.ok('Request for "${request.url}"');
}

// Sensitive information
const String username = 'admin';
const String password = 'password123';
const String email = 'admin@example.com';
const String api_key = '123456789abcdef';
        
        

The above Dart code is a simple server application using the Shelf framework. It listens for requests on localhost:8080 and responds with a message containing the requested URL.

However, the code contains a major security vulnerability: it stores sensitive information directly in the source code. The username, password, email, and API key are all stored as plain text constants. This is a common mistake, but it is a serious security risk.

Anyone who has access to the source code can see these credentials. This could be a malicious insider, or someone who gains unauthorized access to the source code. They could use these credentials to gain unauthorized access to systems, carry out actions on behalf of the user, or leak the credentials.

Furthermore, storing credentials in the source code makes them hard to change. If you need to change the password or API key, you have to change the source code and redeploy the application.

This is a clear violation of the principle of least privilege, which states that code (and people) should only have the minimum privileges necessary to perform their function. In this case, the code has access to credentials that it should not have.

The credentials should be stored securely, for example in environment variables or a secure vault, and accessed through a secure method.

Steps

  • Remove the hard-coded sensitive information from the source code.
  • Store sensitive information in environment variables or a secure configuration file that is not included in the version control system.
  • Use a secure method to access these environment variables or configuration files in your code.
  • Consider using a secret management system or service for storing and managing sensitive information.
  • Ensure that the sensitive information is encrypted when at rest and in transit.
  • Implement proper error handling so that no sensitive information is leaked in error messages or logs.

Compliant code

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

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

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

shelf.Response _echoRequest(shelf.Request request) {
  return shelf.Response.ok('Request for "${request.url}"');
}

// Sensitive information
final String username = Platform.environment['USERNAME'];
final String password = Platform.environment['PASSWORD'];
final String email = Platform.environment['EMAIL'];
final String api_key = Platform.environment['API_KEY'];
        
        

The original code contained sensitive information such as username, password, email, and API key as hard-coded constants. This is a security vulnerability as it exposes these sensitive details in the source code which could be exploited by malicious users.

The updated code removes these hard-coded values and instead retrieves them from environment variables. This is a more secure practice as it ensures that these details are not exposed in the source code. The Platform.environment in Dart is used to access these environment variables.

To use this updated code, you would need to set the environment variables USERNAME, PASSWORD, EMAIL, and API_KEY in the environment where your Dart code is running.

This change helps to protect the sensitive information from being exposed in the source code. However, it is also recommended to use a secret management system or service for storing and managing sensitive information, and to ensure that the sensitive information is encrypted when at rest and in transit.

Additionally, proper error handling should be implemented so that no sensitive information is leaked in error messages or logs.

References