Lack of data validation - HTML code - Dart

Lack of data validation - HTML code - Dart

Need

Ensure proper data validation and sanitization to prevent HTML code injection

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;

shelf.Response handleRequest(shelf.Request request) {
  var body = request.readAsString();
  return shelf.Response.ok(body);
}
        
        

In the above Dart code, we have a simple server that uses the Shelf framework. The server receives a request and directly sends the content of the request back as a response. This is a very basic echo server.

The vulnerability lies in the handleRequest function. This function reads the body of the request as a string and directly sends it back as the response without performing any form of data validation or sanitization.

This means if a user sends a request with HTML code in the body, the server will return that HTML code back in the response. If this response is interpreted by a web browser, then the HTML code will be executed. This is a form of Cross-Site Scripting (XSS) attack, where an attacker can inject malicious scripts to be executed by the user's browser.

The server should not trust user input blindly and should always sanitize and validate it before using it.

Steps

  • Introduce a data validation layer before sending the response.
  • Use a library or built-in function to sanitize the input and remove or escape any HTML tags.
  • Ensure that the sanitized data is the data that gets sent in the response, not the original, potentially malicious data.
  • Consider using a Content Security Policy (CSP) to add an extra layer of security and prevent any injected code from running.

Compliant code

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

shelf.Response handleRequest(shelf.Request request) {
  var body = request.readAsString();
  var sanitizedBody = HtmlEscape().convert(body);
  return shelf.Response.ok(sanitizedBody);
}
        
        

The original code was vulnerable to HTML injection because it directly used the body of the request as the body of the response without any validation or sanitization. This means that if the request body contained any HTML code, it would be included in the response and could potentially be interpreted by the client, leading to various types of attacks such as Cross-Site Scripting (XSS).

The fixed code introduces a data validation layer before sending the response. It uses the HtmlEscape class from the html_escape package to sanitize the input and remove or escape any HTML tags. This ensures that the sanitized data is the data that gets sent in the response, not the original, potentially malicious data.

In addition to this code-level fix, it is also recommended to use a Content Security Policy (CSP) to add an extra layer of security and prevent any injected code from running. This would be configured at the server level, not in the Dart code itself.

References