Skip to main content

Insecure service configuration - Object Reutilization

Need

Secure object reutilization management

Context

  • Usage of Dart for building cross-platform mobile, web, and desktop 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;

class SingletonObject {
static SingletonObject _instance;

SingletonObject._internal();

static SingletonObject getInstance() {
if (_instance == null) {
_instance = new SingletonObject._internal();
}
return _instance;
}
}

void handleRequest(shelf.Request request) {
SingletonObject instance = SingletonObject.getInstance();
// perform operations using the instance
}

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

shelf.serve(handler, 'localhost', 8080).then((server) {
print('Serving at http://${server.address.host}:${server.port}');
});
}

In the code snippet above, we have a Singleton class SingletonObject that reuses the same instance for every request coming to the handleRequest function. This can lead to severe security issues like data leakage between different users' sessions if the singleton object stores any user-specific data.

The Singleton design pattern is meant to ensure that a class has only one instance, and provide a global point of access to it. However, in a multi-user environment like a web server, this can create problems if not handled correctly. For example, if the Singleton class is used to store user-related data, then that data will be shared among all users, leading to data leakage.

The handleRequest function uses the SingletonObject instance to perform some operations. Since the same instance is reused for every request, if the instance stores any state that is specific to a request, that state will be shared among all requests, which can lead to data leakage and other security issues.

This is a classic case of insecure service configuration - Object Reutilization vulnerability. The system does not validate that objects, data or information, valid for one use only can be reused.

Steps

  • Introduce a mechanism to invalidate the SingletonObject instance after its use. This can be done by adding a method in the SingletonObject class that sets the _instance to null.
  • Ensure that the SingletonObject instance is invalidated after each request in the handleRequest function. Call the invalidation method after the operations using the instance are performed.
  • Add checks to ensure that the SingletonObject instance is not being used after it has been invalidated. This can be done by throwing an exception if methods are called on an invalidated instance.

Compliant code

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

class SingletonObject {
static SingletonObject _instance;

SingletonObject._internal();

static SingletonObject getInstance() {
if (_instance == null) {
_instance = new SingletonObject._internal();
}
return _instance;
}

static void invalidateInstance() {
_instance = null;
}

void validateInstance() {
if (_instance == null) {
throw Exception('Instance has been invalidated');
}
}
}

void handleRequest(shelf.Request request) {
SingletonObject instance = SingletonObject.getInstance();
instance.validateInstance();
// perform operations using the instance
SingletonObject.invalidateInstance();
}

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

shelf.serve(handler, 'localhost', 8080).then((server) {
print('Serving at http://${server.address.host}:${server.port}');
});
}

The code above fixes the vulnerability by introducing a mechanism to invalidate the SingletonObject instance after its use. This is done by adding a method invalidateInstance in the SingletonObject class that sets the _instance to null.

In the handleRequest function, after performing operations using the instance, the invalidateInstance method is called to invalidate the SingletonObject instance. This ensures that the SingletonObject instance is invalidated after each request.

A validateInstance method is also added to the SingletonObject class to check if the SingletonObject instance is being used after it has been invalidated. This method is called before performing operations using the instance in the handleRequest function. If the SingletonObject instance has been invalidated (i.e., _instance is null), an exception is thrown. This prevents the reuse of invalidated objects, data, or information, thereby fixing the vulnerability.

References