Skip to main content

Privacy violation

Need

Protection of user privacy

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;

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

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

shelf.Response _echoRequest(shelf.Request request) {
// Echoes the request headers back in the response body
var data = request.headers.entries.map((h) => '${h.key}: ${h.value}').join('\\n');
return shelf.Response.ok(data);
}

In the above code, we have a simple server that listens on localhost:8080 and echoes back the headers of any request it receives. The vulnerable part of this code is in the _echoRequest function. Here, we are taking all the headers from a request and sending them back in the response.

This is a privacy violation because HTTP headers can contain sensitive information. For example, they often include cookies, which might be used to authenticate a user. By echoing these back in the response, we are potentially exposing this sensitive information to anyone who can intercept the response. This could be an attacker who is eavesdropping on the network, or it could be any third-party JavaScript code running in the user's browser if the response is being sent there.

Additionally, the code does not have any checks or filters to remove or obfuscate sensitive headers before echoing them back. This means that all headers, regardless of their sensitivity, are being exposed.

Steps

  • Identify the sensitive information in the headers that should not be echoed back.
  • Create a list of these sensitive headers that should be excluded.
  • Modify the '_echoRequest' function to filter out these sensitive headers when creating the 'data' variable.

Compliant code

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

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

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

shelf.Response _echoRequest(shelf.Request request) {
// List of sensitive headers that should not be echoed back
var sensitiveHeaders = ['authorization', 'cookie', 'set-cookie'];

// Echoes the request headers back in the response body, excluding sensitive headers
var data = request.headers.entries
.where((h) => !sensitiveHeaders.contains(h.key.toLowerCase()))
.map((h) => '${h.key}: ${h.value}')
.join('\\n');

return shelf.Response.ok(data);
}

The original code was echoing back all the headers received in the request, including potentially sensitive ones like 'authorization', 'cookie', and 'set-cookie'. This could lead to privacy violations as these headers often contain sensitive user information.

The fixed code first defines a list of sensitive headers that should not be echoed back. This list includes 'authorization', 'cookie', and 'set-cookie', but can be extended to include any other headers that are considered sensitive in the context of the application.

The '_echoRequest' function is then modified to filter out these sensitive headers when creating the 'data' variable. This is done using the 'where' function to exclude any headers whose key is in the 'sensitiveHeaders' list. The key is converted to lower case before the comparison to ensure that the filtering is case-insensitive.

As a result, the response will still include the headers from the request, but any sensitive headers will be excluded, thus preserving the privacy of the user's information.

References