JSON Cookies with Express

express provides a little known facility for storing JavaScript objects in cookies, and it’s surprisingly simple to use. Just pass a JavaScript object instead of a string for the cookie value to cause JSON.stringify() and JSON.parse() to be run in the background when storing and parsing a cookie.

'use strict';

const express = require('express');
const cookieParser = require('cookie-parser');

const app = express();

app.use(cookieParser('cheese'));

app.get('/', (req, res) => {
    res.cookie('j:cheeses', [
        'cheddar',
        'gouda',
        'munster',
        'mozzarella'
    ], {
        signed: true,
        expires: new Date(Date.now() + 1000000),
        httpOnly: true
    });
    res.redirect('show');
});

app.get('/show', (req, res) => {
    const cheeses = req.signedCookies['j:cheeses'] || [];
    res.clearCookie('j:cheeses');
    res.json(cheeses);
});

app.listen(3000);

Emulating ES6 template strings in ES5 with _.template() from lodash

A cool new feature in ECMAScript 2015 (ES6) is template strings. It lets you put variables in your strings without the awkward string concatenation.

This ES5 code:

 var message = 'Hello, ' + user.firstName + ' ' + user.lastName;

could be written like this in ES6:

var message = `Hello, ${user.firstName} ${user.lastName}`;

If you aren’t able to use ES6 yet and wish to emulate that feature, you can get a rough approximation with _.template() from lodash. You just need to set the interpolate option to /\$\{([^\}]+)\}/gm. Then you build a little formatter function like this:

function fmtr(str, obj) {
    return _.template(_.isString(str) ? str : '', { interpolate: /\$\{([^\}]+)\}/gm })(obj);
}

With that function, you can use templates like this:

var message = fmtr('Hello, ${firstName} ${lastName}', user);

I’ve found it super useful in a number of projects and have packaged it up in a node.js module named fmtr.

While it isn’t as powerful as string templates in one way (you have to pass an object to it with the variables you want to substitute into the string), it is more powerful in another way. You can use it as the foundation for bigger and better things. For example, I built an LDAP escaper module named ldap-escape to prevent LDAP injection attacks; it escapes the values and then applies the template like this:

var safeDn = ldapEscape.dn('cn=${cn},dc=test', alice);

 

Computing Password Strength

Password strength largely depends on the search space for guessing the password by trying every possibility. The longer the password is and the wider variety of character classes used, the harder it is to guess via brute force. A good metric for password strength is the number of bits of entropy. This can be computed by taking the binary logarithm of the sum of the size of the character classes contained in the password where the character classes are digits, lower case letters, upper case letters, and special characters. The following JavaScript function performs that computation:

function passwdStrength(passwd) {
    return passwd.length * Math.log2([
        { r: /[0-9]/, size: 10 },
        { r: /[A-Z]/, size: 26 },
        { r: /[a-z]/, size: 26 },
        { r: /[^0-9A-Za-z]/, size: 33 }
    ].reduce(function (sum, clazz) {
        if (clazz.r.test(passwd)) {
            sum += clazz.size;
        }
        return sum;
    }, 0));
}

The above function returns a number related to the strength of the password, but how do you know what’s good enough? Well, RFC4086 has a section on Password Generation that explains how much entropy you need.

There’s one more thing. People re-use passwords, and two different people can also come up with the same password. Attackers often use lists of known passwords when trying to guess a password before attempting to guess via brute force. One could have a high entropy password like “iloveyou1234”, but if it is a known password, it could be guessed in under a second. When creating a new password, it is important to check it against a list of common passwords. A huge trove of known passwords is available through the SecLists archive.

I’ve built a node.js module called passwd-strength around the above function and it includes a check against a database of about 30,000 of the most common passwords.