How to fix NodeJS “CERT_UNTRUSTED” Issues

Have you ever encountered the niggling “CERT_UNTRUSTED” or “UNABLE_TO_VERIFY_LEAF_SIGNATURE” errors in NodeJS? It is probably one of the most annoying and frustrating issues you’ll ever encounter in Node. When does this issue occur and why? Well whenever you try to access a secure URL/endpoint using HTTPS from your NodeJS app but the Certificate Authorities/CAs (usually the Intermediate ones) in the Certificate Chain used to create the SSL certificate used by the secure URL wasn’t bundled properly (Ughhh!). Yea, Annoying right? Of course NodeJS, being a JavaScript-based web server technology, will thus try to protect your app from a man-in-the-middle attack and complain that it does not trust the SSL certificate. So don’t go cursing Node now, it’s just trying to protect you.

The Wrong Way

So what’s the solution? You’ll likely surf around the Net for solutions and hear a lot of folks telling you that you should modify the HTTPS header options to set the RejectUnauthorized property to false in NodeJS. Like so:


var https = require('https');
var options = {
hostname: 'encrypted.google.com',
port: 443,
path: '/',
method: 'GET',
rejectUnauthorized: false
};
var req = https.request(options, function(res) {
}

view raw

thewrongway.js

hosted with ❤ by GitHub

However that is a very, very bad idea, especially if you are writing production level code. Essentially by setting the RejectUnauthorized property to false, you are in effect allowing ALL certificates to be accepted by NodeJS, and thus making a very big hole in the security of your application. So please, don’t be like the other numb skulls who put this in their production code!

The Right Way

Fortunately, for every wrong way, there are several right ways of doing things and you can find many other more secure solutions to resolve this issue. The recommended way to resolve this is by simply including a local copy of the SSL certificate or the certificates of the CAs in the certificate chain, within your NodeJS app and configuring that in the HTTPS header options. In that way, Node will have something to evaluate the SSL certificate chain against, and thus be able to trust it.   Therefore if you have the actual SSL Certificate you are good to go! You can just configure your HTTPS header options to use it. Like so:


var https = require('https');
var fs = require('fs');
var options = {
hostname: 'encrypted.google.com',
port: 443,
path: '/',
method: 'GET',
key: fs.readFileSync('/ yourapp/certs/key.pem'),
cert: fs.readFileSync('/yourapp/certs/cert.pem'),
rejectUnauthorized: true
};
options.agent = new https.Agent(options);
var req = https.request(options, function(res) {
}

view raw

usingcert.js

hosted with ❤ by GitHub

In the example above we configure the key and cert properties of the header options to use the values of the certificate and key files required to access the secure URL/endpoint.  These files would have already had the certificate chain bundled within them and thus should work fine.

However, if you don’t have access to the actual SSL Certificate, things may get a little stickier. You may need to configure Node with the public certificates of the CAs in the certificate chain.

Thanks to folks like coolaj86 we have node modules that can assist us in downloading the public certificates of most known CAs that we can then use to configure our NodeJS app.  You can check out his GitHub repository at https://github.com/coolaj86/node-ssl-root-cas for further information on how to install and use the module node-ssl-root-cas.

Of course, if you have knowledge of the certificate chain the SSL certificate uses, you could also download the public certificates of the CAs within the certificate chain yourself and configure them in the HTTPS header options without using a node module like node-ssl-root-cas. For example, you could download the public certificate of the Root CA and any Intermediate CAs in the chain and configure them like so:


var https = require('https');
var fs = require('fs');
var options = {
hostname: 'encrypted.google.com',
port: 443,
path: '/',
method: 'GET',
ca: [fs.readFileSync('/yourapp/certs/intCA1Cert.pem'), fs.readFileSync('/yourapp/certs/ rootCACert.pem')],
rejectUnauthorized: true
};
options.agent = new https.Agent(options);
var req = https.request(options, function(res) {
}

Here we configure the ca array property of the header options to use the values of the public certificate files for the Root and Intermediate CAs from the certificate chain of the SSL certificate required to access the secure URL/endpoint. This works just as effectively!

A cleaner way

However there is a cleaner way to do this. You could create a certificate bundle file that includes your certificate and the public certificates of the CAs (i.e. Root and Intermediates) that your SSL certificate uses. You can then configure the HTTPS headers for Node to use the bundle file when making requests. Like so:


var https = require('https');
var fs = require('fs');
var options = {
hostname: 'encrypted.google.com',
port: 443,
path: '/',
method: 'GET',
key: fs.readFileSync('/yourapp/certs/privkey.pem'),
cert: fs.readFileSync('/yourapp/certs/bundle.pem'), // a PEM containing the SERVER and ALL INTERMEDIATES
rejectUnauthorized: true
};
options.agent = new https.Agent(options);
var req = https.request(options, function(res) {
}

Here we create a bundle.pem file that contains the SSL certificate and the public certificates of all the Intermediate CAs as well as the Root CA. We then configure the key and cert properties of the HTTPS header options to use the values of the bundle and private key files.

In Conclusion

“CERT_UNTRUSTED” or “UNABLE_TO_VERIFY_LEAF_SIGNATURE” errors are annoying but justifiably so. Don’t let it ruin your day, or your love for the fantastic platform that NodeJS is, or make you feel so frustrated that you go and sacrifice the security of your web app.  There is a reason why you chose to use Secure HTTP and there are good reasons why Node wants to help you enforce that. Never sacrifice the quality of your application trying to fix what are essentially relatively minor issues the wrong way, especially when there are several right ways of fixing them that maintains the security of your application. Small sacrifices may lead to BIGGER problems in the future! I hope the information provided in this blog post can save someone’s day. Cheers!

Testing Private JavaScript : “To Test, Or Not To Test”

Testing private JavaScript, that is JavaScript in closures, has always been a dilemma for the JavaScript Developer that wants to practice TDD. There have been many debates and schools of thought around this. Some believe that private JavaScript functions and objects should not be tested and attempting to do so could violate good JavaScript design practice. Such reasoning however ignores the virtues of TDD in contributing to code and overall application quality.

Good JavaScript design practice dictates that you will probably want to abstract all your core functionality into a closure, essentially making your core objects and functions private. The main reason for this is that client-side JavaScript is easily accessible within the user’s browser. Thus all your functionality and implementation code is available and viewable within the browser. Also if there are other JavaScript functions publicly accessible within the page that has a similar definition to the functions in your library, it could cause conflicts when trying to interact with them at runtime. Furthermore following object-oriented rules of encapsulation and abstraction, you want to extract your internal implementation into private objects and functions away from the public view.

However this presents a problem, as functionality within closures are not accessible publicly and thus are inaccessible by testing frameworks to be able to unit test your code. So if you are an avid proponent of TDD and want to ensure your code is robust and working as it should, while adhering to good JavaScript design principles, how do you get around this and strike a balance?

Testing Private functions through a Public Interface

The first thing you probably want to do is create a public interface for your library to expose your functionality publicly. An example of how this would look is given here:


(function(){ //opens the closure
//definition of private object Animal
var Animal= function(){
this.name="";
};
Animal.prototype={
getAnimal : function(code){
if(code=="c"){
this.name="Cat";
}
else if(code=="d"){
this.name="Dog";
}
else{
this.name="unknown";
}
}
};
//myLib public interface
window.myLib = {
selectAnimal : function(code){
var selector=new Animal();
selector.getAnimal(code);
return selector.name;
}
};
})(); //closes the closure
//Call selectAnimal publicly
window.myLib.selectAnimal();

view raw

example1.js

hosted with ❤ by GitHub

In the example above, we have a closure that contains a public interface attached to window called myLib and a private object called Animal that does all the heavy lifting. MyLib is accessible publicly and has a public function selectAnimal that takes a parameter called code. All selectAnimal does is create an instance of Animal and returns the value of the Animal object’s name property which is set from a call to it’s getAnimal function with the specified code.

It is the getAnimal function that does all the work. It takes the code specified and through a series of conditions, sets the name property of Animal with the specific name of the animal.

Whereas myLib.selectAnimal is exposed publicly and can be tested easily. Animal is defined within the closure and is private and all it’s related properties and functions are also private, and thus inaccessible by any testing framework.

To ensure getAnimal is fully tested we have to use the public function to fully exercise every scenario that the private function would get called with.

An example of tests for this using the Jasmine Testing framework would be:


describe("The selectAnimal function", function(){
it("should return Cat"){
expect(window.myLib.selectAnimal("c")).toBe("Cat");
};
it("should return Dog"){
expect(window.myLib.selectAnimal("d")).toBe("Dog");
};
it("should return unknown"){
expect(window.myLib.selectAnimal()).toBe("unknown");
}
});

These tests would fully test both the public function selectAnimal and the private function getAnimal by mimicking every scenario for selectAnimal in which getAnimal may be called.

Hence when conceptualizing our tests, in true TDD style, conceptualize your tests for the private functions and view the public function as just a wrapper for your core implementation.

Though it might be tricky, depending on the level of complexity, to conceptualize tests for every scenario that would exercise both a public function and any potential private functions it may use, it is not impossible and if you are following detailed methods of conceptualizing your tests, this shouldn’t be difficult.

The same approach goes for standalone functions defined within the closure. For example, lets modify our code to let selectAnimal receive a JSON object, and we send that to a utility function defined within the closure:


(function(){ //opens the closure
//utility function
function extractCode(obj){
return obj.code;
};
//definition of private object Animal
var Animal= function(){
this.name="";
};
Animal.prototype={
getAnimal : function(code){
if(code=="c"){
this.name="Cat";
}
else if(code=="d"){
this.name="Dog";
}
else{
this.name="unknown";
}
}
};
//myLib public interface
window.myLib = {
selectAnimal : function(params){
var selector=new Animal();
var code = extractCode(params);
selector.getAnimal(code);
return selector.name;
}
};
})(); //closes the closure
//Call selectAnimal publicly with JSON data
window.myLib.selectAnimal({"code":"d"});

view raw

example2.js

hosted with ❤ by GitHub

Here we added a utility function extractCode that is a standalone function defined within the closure, and is thus also private. We use extractCode to extract the value for code from the JSON object received by selectAnimal. This example would not require any additional tests for selectAnimal to exercise extractCode as well since all extractCode does is return the code, but you get the general idea.

An Alternative Approach: Adding a Public Instance of the Private Object

Another approach would be to add a public instance of the private object to the public interface. So we could modify our solution to include a property of myLib that instantiates an instance of Animal. For example:


(function(){ //opens the closure
//definition of private object Animal
var Animal= function(){
this.name="";
};
Animal.prototype={
getAnimal : function(code){
if(code=="c"){
this.name="Cat";
}
else if(code=="d"){
this.name="Dog";
}
else{
this.name="unknown";
}
}
};
//myLib public interface
window.myLib = {
selector : null,
initialize : function(){
//public property instantiates an instance of Animal
this.selector= new Animal();
},
selectAnimal : function(code){
this.selector.getAnimal(code);
return this.selector.name;
}
};
})(); //closes the closure
//initializes selector publicly
window.myLib.initialize();
//Call selectAnimal publicly
//Returns 'Dog'
window.myLib.selectAnimal("d");

view raw

example3.js

hosted with ❤ by GitHub

So here, all we do is make the selector variable a public property of window.myLib and use it to initialize an instance of the Animal object in our initialize function. So now when we call the getAnimal function, we use the this self referencer to access the public property like so: this.selector.getAnimal.

This now gives us an instance of Animal that is accessible publicly. We can use that in our tests to test the private object and its related functions directly. Example:


describe("The getAnimal function", function(){
beforeEach(function(){
window.myLib.initialize();
});
it("should set Animal name property to Cat"){
window.myLib.selector.getAnimal("c")
expect(window.myLib.selector.name).toBe("Cat");
};
it("should set Animal name property to Dog"){
window.myLib.selector.getAnimal("d")
expect(window.myLib.selector.name).toBe("Dog");
}
it("should set Animal name property to unknown"){
window.myLib.selector.getAnimal()
expect(window.myLib.selector.name).toBe("unknown");
}
});
describe("The selectAnimal function", function(){
it("should call the getAnimal function"){
window.myLib.initialize();
spyOn(window.myLib.selector, "getAnimal");
window.myLib.selectAnimal();
expect(window.myLib.selector.getAnimal).toHaveBeenCalled();
};
});

Now that we are able to test getAnimal independently, we can reduce our tests for selectAnimal, as shown.

Personally I prefer this approach as I consider it perhaps the easiest and cleanest way to expose your private functionality to your tests without severely violating good JavaScript design principles.

Testing Callback functions without mocking asynchronous calls

Callback functions are commonly used in asynchronous calls such as AJAX requests. Though there are many third party mocking libraries that simulate asynchronous calls that can allow these functions to be tested, in an environment with little or no use of third party libraries, this can be a real challenge to test. Well now that we have our public instance of our private object, this becomes significantly simpler. Lets modify our code snippet to include an AJAX call using JQuery’s ajax function:


(function(){ //opens the closure
//definition of private object Animal
var Animal= function(){
this.name="";
};
Animal.prototype={
getAnimal : function(code){
//AJAX call to get the description
$.ajax({
url : "getDescription.json",
dataType : "json",
data : JSON.stringify({"code" : code}),
success : function(response){
this.name=response;
}
});
}
};
//myLib public interface
window.myLib = {
selector : null,
initialize : function(){
//public property instantiates an instance of Animal
this.selector= new Animal();
},
selectAnimal : function(code){
this.selector.getAnimal(code);
return this.selector.name;
}
};
})(); //closes the closure
//initializes selector publicly
window.myLib.initialize();
//Call selectAnimal publicly
//Returns 'Dog'
window.myLib.selectAnimal("d");

view raw

example4.js

hosted with ❤ by GitHub

In the example above we modified our getAnimal function to include an AJAX call made to an endpoint getDescription.json that returns the appropriate description based on the code supplied. Upon a success response, a function is called that sets the name property of the Animal object.

Without the use of some third party library for mocking asynchronous calls, it would be near impossible to test that success function. However making a slight modification to the code can make this function more testable. Example:


(function(){ //opens the closure
//definition of private object Animal
var Animal= function(){
this.name="";
};
Animal.prototype={
getAnimal : function(code){
var s = this;
s.getAnimalCallBackFn = function(response){
this.name=response;
};
//AJAX call to get the description
$.ajax({
url : "getDescription.json",
dataType : "json",
data : JSON.stringify({"code" : code}),
success : s.getAnimalCallBackFn
});
}
};
//myLib public interface
window.myLib = {
selector : null,
initialize : function(){
//public property instantiates an instance of Animal
this.selector= new Animal();
},
selectAnimal : function(code){
this.selector.getAnimal(code)
return this.selector.name;
}
};
})(); //closes the closure
//initializes selector publicly
window.myLib.initialize();
//Call selectAnimal publicly
//Returns 'Dog'
window.myLib.selectAnimal("d");

view raw

example5.js

hosted with ❤ by GitHub

So all we do here is make the callback function a method of the Animal object called getAnimalCallBackFn. So now whenever we create an instance of Animal, we will have access to the getAnimalCallBackFn independently of the ajax call.

Now we can use our public instance of Animal, selector, to test getAnimalCallBackFn. Example:


describe("The getAnimalCallBackFn function", function(){
it("should set Animal name property"){
window.myLib.initialize();
window.myLib.selector.getAnimal ();
window.myLib.selector.getAnimalCallBackFn("dog");
expect(window.myLib.selector.name).toBe("dog");
};
});

Conclusion

Testing private JavaScript functions and objects can be a challenge, but there is no reason for the avid JavaScript TDD enthusiast to feel deterred by those who believe that these functions should not be unit tested. Furthermore testing callback functions can be done independently of asynchronous calls if we have limited ability to use third party libraries. Indeed, we can write testable JavaScript that also adheres to good JavaScript design practice. There are many ways to make your JavaScript more testable, and these are just a few pointers I have found helpful. So then, “Go Forth and Test!”.