Technical information leak - SourceMap - Dart

Technical information leak - SourceMap - Dart

Need

Prevention of technical information leakage through SourceMap files

Context

  • Usage of Dart for building cross-platform mobile, web, and desktop applications
  • Usage of Shelf for managing and organizing data in Node.js applications
  • Usage of shelf_io for managing and interacting with data storage in Node.js

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) {
  return shelf.Response.ok('Request for "${request.url}"');
}
        
        

This is a simple backend application written in Dart using the Shelf framework. The main function sets up a server that listens on localhost:8080. The server uses a pipeline that logs requests and then sends them to the _echoRequest handler.

The _echoRequest function returns a response with a message that includes the URL of the request.

The vulnerability here is that the application is serving all types of files, including .map files. Source map files are typically used for debugging purposes and they map the minified/combined version of the file back to its original state. However, if these files are exposed to the public, they could potentially provide a lot of information to a malicious actor. This information could include the structure of your code, any hidden APIs or services you're using, and potentially even sensitive data if it's hardcoded into your application.

This is a technical information leak vulnerability because it's exposing internal details of the application that could be used to exploit other vulnerabilities. It's generally a good practice to ensure that .map files and other similar files are not served to the client in a production environment.

Steps

  • Identify and locate all .map files in your application.
  • Configure your server to prevent these .map files from being served to the client. This can be done by modifying the server configuration or using middleware to filter out these files.
  • Ensure that your build process does not generate .map files in production. This can be done by modifying your build scripts or configuration files.
  • Regularly audit your application to ensure that no new .map files are being exposed.

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())
      .addMiddleware(_hideSourceMapFiles)
      .addHandler(_echoRequest);

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

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

shelf.Middleware _hideSourceMapFiles() {
  return (shelf.Handler innerHandler) {
    return (shelf.Request request) async {
      if (request.url.path.endsWith('.map')) {
        return shelf.Response.forbidden('Access Denied!');
      }
      return innerHandler(request);
    };
  };
}
        
        

The updated code includes a middleware function _hideSourceMapFiles that checks if the requested URL ends with '.map'. If it does, the server responds with a 403 Forbidden status, effectively preventing the client from accessing the source map files. This middleware is added to the server pipeline before the main request handler.

This solution prevents the exposure of .map files, which could potentially be used by a malicious actor to analyze the application. It's important to note that this is a runtime solution and it's still recommended to configure your build process to not generate .map files in a production environment. Regular audits should also be conducted to ensure no new .map files are being exposed.

References