Skip to main content

Lack of data validation - Non Sanitized Variables

Need

Implementation of proper input validation and sanitization

Context

  • Usage of Dart 2.0 for building high-performance, cross-platform applications
  • Usage of dart:io for handling input and output operations in Dart
  • Usage of Shelf for building web applications in Dart

Description

Non compliant code

import 'dart:io';

import 'package:shelf/shelf.dart';

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

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

Response _echoRequest(Request request) {
var input = request.url.queryParameters['input'];

Process.run('echo', [input]).then((ProcessResult results) {
print(results.stdout);
});

return Response.ok('Request for "${request.url}"');
}

The above code is an example of a Dart backend application using the Shelf framework. The function _echoRequest receives a request and uses the 'input' query parameter of the request URL to construct a system command Process.run('echo', [input]).

The vulnerability lies in the fact that the input from the request is directly used without any form of sanitization or validation. This means that if a malicious user crafts the input in a certain way, they could potentially inject commands that could be harmful to the system.

For example, if the user sends a request with the input query parameter as ;rm -rf /, the constructed command becomes echo;rm -rf / which would delete all files in the root directory if the application has sufficient permissions. This is a classic example of a command injection vulnerability due to lack of data validation or sanitization.

Steps

  • Validate the input: Before using the user input in the system command, validate it against a set of rules. For example, you can check if the input contains only alphanumeric characters.
  • Sanitize the input: Remove or escape any special characters that could modify the system command. This can be done using a function that escapes or removes special characters.
  • Use parameterized commands: Instead of directly inserting user input into the system command, use a parameterized command where you can safely insert the user input.
  • Limit the privileges of the process: Run the process with the least privileges necessary to perform its task. This can limit the damage if an attacker manages to inject malicious code.
  • Use a safe API: If possible, use a safe API that automatically handles the risks associated with command injection.

Compliant code

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

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

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

Response _echoRequest(Request request) {
var input = request.url.queryParameters['input'];

// Validate and sanitize the input
if (_isValidInput(input)) {
Process.run('echo', [_sanitizeInput(input)]).then((ProcessResult results) {
print(results.stdout);
});
}

return Response.ok('Request for "${request.url}"');
}

bool _isValidInput(String input) {
// Add validation logic here
// For example, check if the input contains only alphanumeric characters
return RegExp(r'^[a-zA-Z0-9]+$').hasMatch(input);
}

String _sanitizeInput(String input) {
// Add sanitization logic here
// For example, escape or remove special characters
return input.replaceAll(RegExp(r'[^\\w\\s]'), '');
}

The updated code includes two new functions: _isValidInput and _sanitizeInput.

The _isValidInput function checks if the input contains only alphanumeric characters. This is a basic validation and you might need to adjust it based on your specific needs. If the input is not valid, the system command is not executed.

The _sanitizeInput function removes or escapes any special characters in the input. This is a basic sanitization and you might need to adjust it based on your specific needs. The sanitized input is then used in the system command.

These changes help to prevent command injection attacks by ensuring that only valid and safe input is used in the system command.

Please note that this is a basic solution and might not cover all possible command injection attacks. For a more comprehensive solution, consider using a safe API that automatically handles the risks associated with command injection, limiting the privileges of the process, and using parameterized commands.

References