encryption – What are my vulnerabilities with this multi-user ACL database approach?

I would like some expert insight. I want to know what my vulnerabilities for this model are.

This is a demo project that I will be following in my production app if all works out securely. My production app will include hybrid encryption for ALL user sensitive data. Nothing sensitive will ever be stored on the server unencrypted. I know I loose query capabilities but thats not the intention of this post. I solely and only want to know the vulnerabilities (if any) of this model below + hybrid encryption. I’m using Parse & Back4App.

My main concern (possibly paranoia) is unauthorized access causing data corruption. So, using ACLs in this way plus encryption…

This simple method below is, given authorization, users share their user ID via the server and store it locally so to add it to any new ACL permissions for newly created objects or CRUD actions. I hope this helps better explain what I’m trying to do.

The final question:

  • Is this way of using ACLs vulnerable and if so how?
import 'dart:io';
import 'package:hive/hive.dart';
import 'package:parse_server_sdk/parse_server_sdk.dart';
import 'package:service_acl/user_service.dart';

Future<void> main(List<String> arguments) async {
  Hive.init('hive_database');
  await Parse().initialize(
    'DorTmGgGi8QKgEperLDZb3Prin85ViMTvXCt4rdp',
    'https://parseapi.back4app.com',
    clientKey: 'PmT1WWtSYJYnhCBeVxcC2mtBUhWA53cvlgmUsgI4',
    debug: false,
    autoSendSessionId: true,
  );

  ///
  ///
  /// To reset Hive databases
  // var box001 = await Hive.openBox<String>('user_001_group_ids');
  // await box001.clear();

  // var box004 = await Hive.openBox<String>('user_004_group_ids');
  // await box004.clear();

  ///
  ///
  /// To setup application with users and user groups with ACLs
  // await UserService().createAllUsers();

  // sleep(Duration(seconds: 1));

  // await UserService().createUser001Group();
  // await UserService().createUser004Group();

  // sleep(Duration(seconds: 1));

  // await UserService().saveUser001GroupData();
  // await UserService().saveUser004GroupData();

  ///
  ///
  /// To test authorized and unauthorized access
  await UserService().authorizedAccess();
  await UserService().unauthorizedAccess();
}
import 'dart:io';
import 'package:hive/hive.dart';
import 'package:parse_server_sdk/parse_server_sdk.dart';

class UserService {
  static const String user001username = 'User001';
  static const String user001password = 'User001User';
  static const String user001email = 'user001@user001.com';

  static const String user002username = 'User002';
  static const String user002password = 'User002User';
  static const String user002email = 'user002@user002.com';

  static const String user003username = 'User003';
  static const String user003password = 'User003User';
  static const String user003email = 'user003@user003.com';

  static const String user004username = 'User004';
  static const String user004password = 'User004User';
  static const String user004email = 'user004@user004.com';

  static const String user005username = 'User005';
  static const String user005password = 'User005User';
  static const String user005email = 'user005@user005.com';

  static const String user001GroupIDsBox = 'user_001_group_ids';
  static const String user004GroupIDsBox = 'user_004_group_ids';

  List<String> user001GroupIDs = ();
  List<String> user004GroupIDs = ();

  List<ParseObject> user001GroupData = (
    ParseObject('Color')..set('color', 'blue')..set('darkness', 2)..set('lightness', 2),
    ParseObject('Color')..set('color', 'yellow')..set('darkness', 5)..set('lightness', 1),
    ParseObject('Color')..set('color', 'red')..set('darkness', 1)..set('lightness', 5),
    ParseObject('Color')..set('color', 'green')..set('darkness', 3)..set('lightness', 3),
  );

  List<ParseObject> user004GroupData = (
    ParseObject('Color')..set('color', 'brown')..set('darkness', 5)..set('lightness', 4),
    ParseObject('Color')..set('color', 'pink')..set('darkness', 3)..set('lightness', 5),
    ParseObject('Color')..set('color', 'purple')..set('darkness', 2)..set('lightness', 4),
    ParseObject('Color')..set('color', 'orange')..set('darkness', 4)..set('lightness', 1),
  );

  ///
  ///
  /// Creates all users on Parse server
  Future<void> createAllUsers() async {
    final ParseUser user001 = ParseUser.createUser(user001username, user001password, user001email);
    ParseResponse creationRequest001 = await user001.signUp();
    (creationRequest001.success)
        ? print('User 001 created successfully')
        : print(creationRequest001.error!.message);

    final ParseUser user002 = ParseUser.createUser(user002username, user002password, user002email);
    ParseResponse creationRequest002 = await user002.signUp();
    (creationRequest002.success)
        ? print('User 002 created successfully')
        : print(creationRequest002.error!.message);

    final ParseUser user003 = ParseUser.createUser(user003username, user003password, user003email);
    ParseResponse creationRequest003 = await user003.signUp();
    (creationRequest003.success)
        ? print('User 003 created successfully')
        : print(creationRequest003.error!.message);

    final ParseUser user004 = ParseUser.createUser(user004username, user004password, user004email);
    ParseResponse creationRequest004 = await user004.signUp();
    (creationRequest004.success)
        ? print('User 004 created successfully')
        : print(creationRequest004.error!.message);

    final ParseUser user005 = ParseUser.createUser(user005username, user005password, user005email);
    ParseResponse creationRequest005 = await user005.signUp();
    (creationRequest005.success)
        ? print('User 005 created successfully')
        : print(creationRequest005.error!.message);
  }

  ///
  ///
  /// Compiles list of authorized users to user001 group
  Future<void> createUser001Group() async {
    final user001 = ParseUser(user001username, user001password, user001email);
    final user001LoginAttempt = await user001.login();
    if (user001LoginAttempt.success) {
      print('User 001 login successful');
      var box = await Hive.openBox<String>(user001GroupIDsBox);
      await box.add(user001.objectId!);
      await user001.logout();
    }

    sleep(Duration(seconds: 1));
    final user002 = ParseUser(user002username, user002password, user002email);
    final user002LoginAttepmt = await user002.login();
    if (user002LoginAttepmt.success) {
      print('User 002 login successful');
      var box = await Hive.openBox<String>(user001GroupIDsBox);
      await box.add(user002.objectId!);
      await user002.logout();
    }

    sleep(Duration(seconds: 1));
    final user003 = ParseUser(user003username, user003password, user003email);
    final user003LoginAttempt = await user003.login();
    if (user003LoginAttempt.success) {
      print('User 003 login successful');
      var box = await Hive.openBox<String>(user001GroupIDsBox);
      await box.add(user003.objectId!);
      await user003.logout();
    }
  }

  ///
  ///
  /// Compiles list of authorized users to user004 group
  Future<void> createUser004Group() async {
    final user004 = ParseUser(user004username, user004password, user004email);
    final user004LoginAttempt = await user004.login();
    if (user004LoginAttempt.success) {
      print('User 004 login successful');
      var box = await Hive.openBox<String>(user004GroupIDsBox);
      await box.add(user004.objectId!);
      await user004.logout();
    }

    sleep(Duration(seconds: 1));
    final user005 = ParseUser(user005username, user005password, user005email);
    final user005LoginAttempt = await user005.login();
    if (user005LoginAttempt.success) {
      print('User 005 login successful');
      var box = await Hive.openBox<String>(user004GroupIDsBox);
      await box.add(user005.objectId!);
      await user005.logout();
    }
  }

  ///
  ///
  /// Save user001 data to server with group ACLs
  Future<void> saveUser001GroupData() async {
    final acls = ParseACL();
    var box = await Hive.openBox<String>(user001GroupIDsBox);
    user001GroupIDs = box.values.toList();

    for (final id in user001GroupIDs) {
      acls.setReadAccess(userId: id, allowed: true);
      acls.setWriteAccess(userId: id, allowed: true);
    }

    for (final color in user001GroupData) {
      color.setACL(acls);
      await color.save();
    }
  }

  ///
  ///
  /// Save user004 data to server with group ACLs
  Future<void> saveUser004GroupData() async {
    final acls = ParseACL();
    var box = await Hive.openBox<String>(user004GroupIDsBox);
    user004GroupIDs = box.values.toList();

    for (final id in user004GroupIDs) {
      acls.setReadAccess(userId: id, allowed: true);
      acls.setWriteAccess(userId: id, allowed: true);
    }

    for (final color in user004GroupData) {
      color.setACL(acls);
      await color.save();
    }
  }

  ///
  ///
  /// Test authorized access- user002 to access user001 group database
  Future<void> authorizedAccess() async {
    final user002 = ParseUser(user002username, user002password, user002email);
    final user002LoginAttepmt = await user002.login();
    if (user002LoginAttepmt.success) {
      print('User 002 login successful');

      QueryBuilder<ParseObject> colorQuery = QueryBuilder<ParseObject>(ParseObject('Color'));
      final ParseResponse response = await colorQuery.query();

      if (response.success && response.results != null) {
        print(response.results.toString());
      }
      await user002.logout();
      print('User 002 logged out successfully');
    }
  }

  ///
  ///
  /// Test unauthorized access- no login tolken
  Future<void> unauthorizedAccess() async {
      QueryBuilder<ParseObject> colorQuery = QueryBuilder<ParseObject>(ParseObject('Color'));
      final ParseResponse response = await colorQuery.query();

      if (response.success && response.results != null) {
        print(response.results.toString());
      } else {
        print('Error: ' + response.error!.message.toString());
      }
  }
}