Non-encrypted confidential information - Dart

Non-encrypted confidential information - Dart

Need

Secure storage 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) {
  // Storing confidential information in plain text
  var confidentialInfo = 'This is some confidential information';

  return shelf.Response.ok('You sent: ${request.url}, data: $confidentialInfo');
}
        
        

In the above Dart code, we are using the Shelf package, which is a middleware system for Dart server-side applications. We have a server running on localhost port 8080.

The vulnerability lies within the _echoRequest function. Here, we are storing confidential information in the variable confidentialInfo in plain text. When a request is made to the server, the server responds with the confidential information without any encryption.

This means that if an attacker can intercept the server's response, they will be able to see the confidential information in plain text. This is a serious security risk as it exposes sensitive data.

The correct approach would be to store and transmit this confidential information in an encrypted format. This way, even if an attacker intercepts the server response, they will not be able to understand the confidential information without the decryption key.

Steps

  • Identify the confidential information that needs to be encrypted.
  • Choose an encryption algorithm suitable for your needs. AES is a commonly used symmetric encryption algorithm.
  • Before storing or transmitting the confidential information, encrypt it using the chosen algorithm.
  • Ensure that the encryption key is securely stored and managed. It should not be hard-coded in the application.
  • When the confidential information needs to be used, decrypt it using the same encryption key.
  • Ensure that all instances of the confidential information in the code are replaced with the encrypted version.

Compliant code

        import 'dart:convert';
import 'dart:typed_data';
import 'package:shelf/shelf.dart' as shelf;
import 'package:encrypt/encrypt.dart' as encrypt;

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

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

shelf.Response _echoRequest(shelf.Request request) {
  // Confidential information
  var confidentialInfo = 'This is some confidential information';

  // Encrypt the confidential information
  final key = encrypt.Key.fromUtf8('my secure key');
  final iv = encrypt.IV.fromLength(16);
  final encrypter = encrypt.Encrypter(encrypt.AES(key));
  final encryptedConfidentialInfo = encrypter.encrypt(confidentialInfo, iv: iv);

  return shelf.Response.ok('You sent: ${request.url}, data: ${encryptedConfidentialInfo.base64}');
}
        
        

The above code fixes the vulnerability by encrypting the confidential information before it is stored.

The encrypt package is used to perform the encryption. The Key.fromUtf8('my secure key') generates a secure key from a UTF8 string. This key is used to create an instance of the Encrypter class with the AES algorithm.

The IV.fromLength(16) generates an initialization vector (IV) of the specified length. The IV is a random string that is used in combination with the key to encrypt the data.

The encrypter.encrypt(confidentialInfo, iv: iv) method is used to encrypt the confidential information. The encrypted data is then converted to a base64 string for storage or transmission.

Please note that the encryption key should be securely stored and managed. It should not be hard-coded in the application as shown in this example.

Also, when the confidential information needs to be used, it can be decrypted using the same encryption key and IV. The encrypter.decrypt(encryptedConfidentialInfo, iv: iv) method can be used for this purpose.

This ensures that even if an attacker is able to access the stored data, they will not be able to understand it without the encryption key.

References