Overriding a low level node.js module

Overriding a low level node.js module

Problem

Amazon S3 allows static website hosting, but with a requirement that the bucket name must match your domain name. This means your bucket name will look like: mydomain.com. Amazon S3 also provides a wildcard SSL certificate for *.s3.amazonaws.com. By the rules of TLS, this means com.s3.amazonaws.com IS covered by the certificate, but mybucket.com.s3.amazonaws.com is not. Node applications, like Knox that connect to *.com.s3.amazonaws.com should really be able to trust that certificate, even though it breaks the rules of TLS, since the knox library is a ‘closed system’: it only ever connects to an Amazon property.

The Node module https relies on tls.js, and tls.js has this function:

function checkServerIdentity(host, cert) {
...
// "The client SHOULD NOT attempt to match a presented identifier in
// which the wildcard character comprises a label other than the
// left-most label (e.g., do not match bar.*.example.net)."
// RFC6125
if (!wildcards && /*/.test(host) || /[.*].**/.test(host) ||
    /*/.test(host) && !/*.*..+..+/.test(host)) {
   return /$./;
 }

Which will properly return a “Certificate Mismatch” error. Can the upper level Knox module override the checkServerIdentity function, which is several levels down and not called directly by Knox? I know how to override a function in a library I require, but not libraries that are included by these libraries.

Problem courtesy of: regretoverflow

Solution

There is a global cache for modules, which means that any function you override will be modified for all other modules. I think you can include tls yourself and patch checkServerIdentity:

// main.js
var tls = require('tls'),
    mod = require('./mod.js');

tls.checkServerIdentity = function (host, cert) {
  return true;
};

mod.test();
// mod.js
var tls = require('tls');

exports.test = function () {
  console.log(tls.checkServerIdentity()); // true
};
Solution courtesy of: Laurent Perrin

Discussion

Leave a Reply

Your email address will not be published. Required fields are marked *