Skip to main content

Non-encrypted confidential information - Local data

Need

Secure storage of confidential data on local devices

Context

  • Usage of C# for developing robust and efficient applications
  • Usage of System.IO for Input and Output operations in .NET programming
  • Usage of Firebase.Database for real-time data storage and synchronization
  • Usage of Firebase.Database.Query for querying data in the Firebase Realtime Database

Description

Non compliant code

using System.IO;
using Firebase.Database;
using Firebase.Database.Query;

public class FirebaseService
{
private const string FirebaseUrl = "https://your-app.firebaseio.com/";
private const string FirebaseSecret = "your-secret-key";

public async Task StoreDataLocally(string data)
{
var firebaseClient = new FirebaseClient(FirebaseUrl, new FirebaseOptions
{
AuthTokenAsyncFactory = () => Task.FromResult(FirebaseSecret)
});

var dataToStore = await firebaseClient
.Child("Data")
.PostAsync(data);

// Storing data locally in plain text
File.WriteAllText(@"C:\\LocalData\\data.txt", dataToStore);
}
}

The vulnerable code is a C# backend application that uses ASP.NET Core to interact with Firebase. The FirebaseService class has a method StoreDataLocally which stores confidential Firebase data in plain text on the device's local storage.

In the StoreDataLocally method, the Firebase client is initialized with the Firebase URL and secret key. The data is then posted to the Firebase database and stored in the local storage as a plain text file.

The main vulnerability lies in the File.WriteAllText(@"C:\\LocalData\\data.txt", dataToStore); line of code. This line writes the confidential Firebase data to a text file in the local storage in plain text format.

This is a security risk as it allows an attacker who has access to the physical device to view the confidential Firebase data without any encryption in case of theft or loss. It is important to always encrypt confidential data when storing it, especially if it is being stored in a location that can be easily accessed, like the local storage of a device.

Steps

  • Encrypt the confidential data before storing it locally.
  • Use a secure storage mechanism to store the encrypted data.
  • Implement proper access controls and authentication mechanisms to prevent unauthorized access to the stored data.
  • Consider using secure communication protocols (e.g., HTTPS) when communicating with the Firebase database.
  • Regularly update and rotate the Firebase secret key to minimize the risk of unauthorized access.

Compliant code

using System.IO;
using System.Security.Cryptography;
using System.Text;
using Firebase.Database;
using Firebase.Database.Query;

public class FirebaseService
{
private const string FirebaseUrl = "https://your-app.firebaseio.com/";
private const string FirebaseSecret = "your-secret-key";
private const string EncryptionKey = "your-encryption-key"; // Add your encryption key

public async Task StoreDataLocally(string data)
{
var firebaseClient = new FirebaseClient(FirebaseUrl, new FirebaseOptions
{
AuthTokenAsyncFactory = () => Task.FromResult(FirebaseSecret)
});

var dataToStore = await firebaseClient
.Child("Data")
.PostAsync(data);

// Encrypt data before storing
var encryptedData = EncryptData(dataToStore, EncryptionKey);

// Storing data locally in encrypted form
File.WriteAllText(@"C:\\LocalData\\data.txt", encryptedData);
}

private string EncryptData(string data, string key)
{
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
using (Aes aes = Aes.Create())
{
Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(key, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }); // Salt
aes.Key = rfc2898DeriveBytes.GetBytes(32);
aes.IV = rfc2898DeriveBytes.GetBytes(16);
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
cryptoStream.Write(dataBytes, 0, dataBytes.Length);
}

return Convert.ToBase64String(memoryStream.ToArray());
}
}
}
}

The updated code now includes an encryption process before storing the data locally. The EncryptData method uses the AES encryption algorithm to encrypt the data. The Rfc2898DeriveBytes class is used to derive a key from the specified encryption key and a salt. This key is then used to encrypt the data.

The encrypted data is then written to the local storage instead of the plain text data. This ensures that even if an attacker gains access to the physical device and bypasses the device security mechanism, they will not be able to view the confidential data without the encryption key.

In addition to this, it is recommended to use secure communication protocols (e.g., HTTPS) when communicating with the Firebase database and to regularly update and rotate the Firebase secret key to minimize the risk of unauthorized access. Proper access controls and authentication mechanisms should also be implemented to prevent unauthorized access to the stored data.

References