Business information leak - DB - Dart

Business information leak - DB - Dart

Need

Protection of business information stored in the database

Context

  • Usage of Dart for building cross-platform mobile, web, and desktop applications
  • Usage of Shelf for managing database connections and queries

Description

Non compliant code

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

class User {
  String name;
  String documentNumber;
  String walletID;
  String osName;
  String transactionCode;
  String creditCard;
  double balance;

  User(this.name, this.documentNumber, this.walletID, this.osName, this.transactionCode, this.creditCard, this.balance);
}

List users = [
  // List of users with sensitive information
];

shelf.Response userInfoHandler(shelf.Request request) {
  // Vulnerable code: exposing all user information
  String response = '';
  for (var user in users) {
    response += 'Name: ${user.name}, Document Number: ${user.documentNumber}, Wallet ID: ${user.walletID}, OS Name: ${user.osName}, Transaction Code: ${user.transactionCode}, Credit Card: ${user.creditCard}, Balance: ${user.balance}\\n';
  }
  return shelf.Response.ok(response);
}
        
        

In the above code, we have a User class that contains sensitive information such as the user's full name, document number, wallet ID, operating system name, transaction code, associated credit card, and available balance. A list of User objects, users, is created to store this information.

The userInfoHandler function is a request handler for the Shelf framework that is meant to return user information. However, it is currently implemented in a way that it exposes all the sensitive information of all users. This is a serious business information leak vulnerability.

When a client sends a request to this endpoint, the server responds with all the sensitive information of all users. This information can be exploited by malicious users to perform unauthorized transactions, identity theft, and other cyber crimes.

The vulnerability lies in the fact that the server is returning more information than necessary. It is a common best practice to only return the minimal amount of information necessary for the client to perform its function. In this case, sensitive information such as the document number, wallet ID, transaction code, and credit card should not be exposed to the client.

Steps

  • Remove sensitive information from the User class. Only keep necessary information that doesn't compromise security.
  • Implement a proper authentication and authorization system. Only authenticated and authorized users should be able to access their own information.
  • Encrypt sensitive data. If the data must be stored, ensure it is encrypted and cannot be read if intercepted.
  • Avoid exposing all user information in the userInfoHandler function. Only return the necessary information.
  • Implement rate limiting to prevent data scraping.
  • Use secure communication protocols to prevent data interception during transmission.
  • Regularly update and patch your systems to prevent exploitation of known vulnerabilities.

Compliant code

        import 'package:shelf/shelf.dart' as shelf;
import 'package:crypto/crypto.dart';
import 'dart:convert'; // for the utf8.encode method

class User {
  String name;
  String documentNumber;
  String walletID;
  String osName;
  String transactionCode;
  String creditCard;
  double balance;
  String password;

  User(this.name, this.documentNumber, this.walletID, this.osName, this.transactionCode, this.creditCard, this.balance, this.password);
}

List users = [
  // List of users with sensitive information
];

String encryptData(String data) {
  var bytes = utf8.encode(data); // data being hashed
  var digest = sha256.convert(bytes);
  return digest.toString();
}

shelf.Response userInfoHandler(shelf.Request request) {
  // Only return necessary information
  String response = '';
  for (var user in users) {
    response += 'Name: ${user.name}, Wallet ID: ${encryptData(user.walletID)}, OS Name: ${user.osName}\\n';
  }
  return shelf.Response.ok(response);
}
        
        

The code above is a revised version of the original code that had a vulnerability of leaking business information. The changes made are as follows:

- The User class now includes a password field. This is to facilitate the implementation of an authentication system. The password should be hashed and not stored as plain text.
- A new function encryptData has been added. This function takes a string as input and returns the SHA-256 hash of the string. This is used to encrypt sensitive data like the Wallet ID.
- The userInfoHandler function has been modified to only return necessary information. It no longer returns sensitive information like the document number, transaction code, credit card number, and balance. The Wallet ID is returned, but it is encrypted first.
- Note that this is a basic implementation and does not include all the necessary steps to secure the application. For example, it does not include an authentication and authorization system, rate limiting, secure communication protocols, or regular updates and patches. These should be implemented as well.

References