I've been relying heavily on node.js this past year to provide a robust set of tools to solve the problems I encounter on a daily basis. I was pleased to see honorCipherOrder
was added to node's TLS library in node.js v0.7.6, and released with node.js v0.8.0.
Late last year, security researcher Juliano Rizzo announced a new attack against the AES encryption used in the SSL/TLS transaction he dubbed BEAST. The details are interesting to those who care, but it turns out that we can mitigate this attack in node.js by enforcing honorCipherOrder
on the server. Let's take a look.
If you have an HTTPS server that looks like this:
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};
https.createServer(options, function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(443);
...you can now manage the cipher order by using the ciphers
option. In the following code snippet we're going set the options for the above server to use Steve Caligo's cipher order, which prefers TLS 1.2 ciphers (which are not vulnerable to the BEAST attack) for clients that support TLS 1.2 but falls back to the RC4 ciphers on TLS 1.0 clients.[...]
var options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem'),
ciphers: 'ECDHE-RSA-AES256-SHA:AES256-SHA:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM'
};
Finally, we will enforce the cipher order on the server's side of the negotiation:
var options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem'),
ciphers: 'ECDHE-RSA-AES256-SHA:AES256-SHA:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM',
honorCipherOrder: true
};
...which leaves us with the following code for a working server that is not vulnerable to the BEAST attack (in node v0.8.0+!):
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem'),
ciphers: 'ECDHE-RSA-AES256-SHA:AES256-SHA:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM',
honorCipherOrder: true
};
https.createServer(options, function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(443);
Edit, 6/13/2013: Lloyd Watkin has done some research on his own and decided to use a different cipher chain:
ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH
You should read into why he chose it and make an educated decision. </edit>
Until node.js implements this as the defaults (they should), this is something you should implement where using HTTPS with node!
Replies are automatically detected from social media, including Twitter, Facebook, and Google+. To add a comment, include a direct link to this post in your message and it'll show up here within a few minutes.