Skip to main content

Use of an insecure channel - useSslProtocol()

Need

Secure communication channel using SSL/TLS

Context

  • Usage of Dart for building cross-platform mobile, web, and desktop applications
  • Usage of dart:io for handling input and output operations in Dart programming
  • Usage of shelf_io.dart package for handling HTTP requests and responses in Dart using the Shelf framework
  • Usage of Shelf for building web applications in Dart

Description

Non compliant code

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

void main() {
var server = HttpServer.bind(
InternetAddress.loopbackIPv4,
8080,
);

server.then((server) {
server.transform(HttpServerAdapter()).listen((request) {
return Response.ok('Hello, world!');
});
});
}

The above code snippet represents a simple HTTP server using the Shelf framework in Dart. It binds the server to the loopback IPv4 address (localhost) and listens to requests on port 8080.

However, the main vulnerability lies in the use of the HttpServer.bind() function. This function does not use SSL/TLS, which means the data transmitted between the client and the server is not encrypted. This makes the application susceptible to man-in-the-middle (MITM) attacks, where an attacker intercepts the communication between the client and the server to steal sensitive information or inject malicious data.

The use of non-secure HTTP for local development might be acceptable, but it poses a significant security risk in a production environment. It is highly recommended to use secure HTTPS in production to ensure the data integrity and confidentiality.

Steps

  • Replace the use of HttpServer.bind with HttpServer.bindSecure. This will ensure that the server is using SSL/TLS for secure communication.
  • Provide a SecurityContext to the bindSecure method. The SecurityContext should include the server's certificate and private key.
  • Ensure that the certificate and private key are stored securely and are not exposed to potential attackers.
  • Remove any code that disables certificate validation or trusts all certificates. This is often done for testing purposes but should not be used in production.
  • Test the secure server to ensure that it is working correctly and that clients are able to connect to it securely.

Compliant code

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

void main() async {
var context = SecurityContext();
context.useCertificateChain('path/to/certificate.pem');
context.usePrivateKey('path/to/private_key.pem');

var server = await HttpServer.bindSecure(
InternetAddress.loopbackIPv4,
8080,
context,
);

server.transform(HttpServerAdapter()).listen((request) {
return Response.ok('Hello, world!');
});
}

The updated code now uses HttpServer.bindSecure instead of HttpServer.bind. This ensures that the server is using SSL/TLS for secure communication.

A SecurityContext is created and used to provide the server's certificate and private key. The useCertificateChain method is used to provide the path to the server's certificate, and the usePrivateKey method is used to provide the path to the server's private key.

Please replace 'path/to/certificate.pem' and 'path/to/private_key.pem' with the actual paths to your certificate and private key files.

Ensure that these files are stored securely and are not exposed to potential attackers.

The code that disables certificate validation or trusts all certificates has been removed. This is often done for testing purposes but should not be used in production.

After updating the code, test the secure server to ensure that it is working correctly and that clients are able to connect to it securely.

References