Lack of data validation - Type confusion - Dart

Lack of data validation - Type confusion - Dart

Need

Enforce strict data validation to prevent type confusion vulnerabilities.

Context

  • Usage of Dart for building cross-platform mobile, web, and desktop applications
  • Usage of Shelf for managing data storage and retrieval
  • Usage of Shelf.io for managing and organizing data storage

Description

Non compliant code

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

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

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

shelf.Response _echoRequest(shelf.Request request) {
  var number = request.url.queryParameters['number'];
  return shelf.Response.ok('You entered: $number');
}
        
        

In the above code, we have a simple server using the shelf framework. The main function sets up a pipeline with logging middleware and a handler function _echoRequest.

The _echoRequest function is where the vulnerability lies. This function takes the 'number' query parameter from the URL and directly uses it in the response without any validation. The server is expected to only accept numbers. However, due to the lack of data validation, it also accepts hexadecimal values like '0xff'.

This is a type confusion vulnerability. The server is treating the input as a string, even though it expects a number. This could lead to unexpected behavior, errors, or security issues if the input is used in a context where a number is expected.

Steps

  • First, import the 'int' class from Dart's core library.
  • Next, when retrieving the 'number' parameter from the request, parse it as an integer using the 'int.parse()' function.
  • To prevent type confusion, you should handle the FormatException that could be thrown if the parsing fails. This can be done by using a try-catch block.
  • In the catch block, return an error response indicating that the input was not a valid number.
  • Finally, ensure that all instances where the 'number' parameter is used are updated to use the parsed integer value.

Compliant code

        import 'dart:core';
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as io;

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

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

shelf.Response _echoRequest(shelf.Request request) {
  try {
    var number = int.parse(request.url.queryParameters['number']);
    return shelf.Response.ok('You entered: $number');
  } catch (FormatException) {
    return shelf.Response(400, body: 'Invalid number format');
  }
}
        
        

The updated code now includes a try-catch block to handle any FormatException that might occur when parsing the 'number' parameter from the request URL. This exception is thrown when the string cannot be parsed into an integer, which would happen if the string is not a valid number representation (like '0xff').

The int.parse() function is used to convert the 'number' parameter to an integer. If the parsing is successful, the function returns the integer value. If it fails, it throws a FormatException.

In the catch block, we return a shelf.Response with a status code of 400 (Bad Request) and a body message of 'Invalid number format'. This informs the client that the provided 'number' parameter was not in a valid format.

This way, we ensure that the 'number' parameter is always treated as an integer, preventing any type confusion vulnerabilities.

References