Skip to content

Commit

Permalink
tls: more secure defaults
Browse files Browse the repository at this point in the history
Port of io.js commit: nodejs/node@77f3586

Original commit message:

This updates the default cipher suite to an more secure list, which
prefers strong ciphers with Forward Secrecy. Additionally, it enables
`honorCipherOrder` by default.

Noteable effect of this change is that the insecure RC4 ciphers are
disabled and that Chrome negotiates a more secure ECDHE cipher.

Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Fedor Indutny <fedor@indutny.com>
PR-URL: nodejs/node#826
  • Loading branch information
jasnell committed Mar 31, 2015
1 parent 9010dd2 commit 1b1fe53
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 35 deletions.
44 changes: 18 additions & 26 deletions doc/api/tls.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ To create a self-signed certificate with the CSR, do this:

Alternatively you can send the CSR to a Certificate Authority for signing.

(TODO: docs on creating a CA, for now interested users should just look at
`test/fixtures/keys/Makefile` in the Node source code)
For Perfect Forward Secrecy, it is required to generate Diffie-Hellman
parameters:

openssl dhparam -outform PEM -out dhparam.pem 2048

To create .pfx or .p12, do this:

Expand Down Expand Up @@ -170,31 +172,20 @@ automatically set as a listener for the [secureConnection][] event. The
- `crl` : Either a string or list of strings of PEM encoded CRLs (Certificate
Revocation List)

- `ciphers`: A string describing the ciphers to use or exclude.

To mitigate [BEAST attacks] it is recommended that you use this option in
conjunction with the `honorCipherOrder` option described below to
prioritize the non-CBC cipher.

Defaults to
`ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL`.
Consult the [OpenSSL cipher list format documentation] for details
on the format.

`ECDHE-RSA-AES128-SHA256`, `DHE-RSA-AES128-SHA256` and
`AES128-GCM-SHA256` are TLS v1.2 ciphers and used when node.js is
linked against OpenSSL 1.0.1 or newer, such as the bundled version
of OpenSSL. Note that it is still possible for a TLS v1.2 client
to negotiate a weaker cipher unless `honorCipherOrder` is enabled.
- `ciphers`: A string describing the ciphers to use or exclude, separated by
`:`. The default cipher suite is:

`RC4` is used as a fallback for clients that speak on older version of
the TLS protocol. `RC4` has in recent years come under suspicion and
should be considered compromised for anything that is truly sensitive.
It is speculated that state-level actors possess the ability to break it.
ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA256:
DHE-RSA-AES256-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:
HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!SRP:!CAMELLIA

**NOTE**: Previous revisions of this section suggested `AES256-SHA` as an
acceptable cipher. Unfortunately, `AES256-SHA` is a CBC cipher and therefore
susceptible to [BEAST attacks]. Do *not* use it.
The default cipher suite prefers ECDHE and DHE ciphers for Perfect Forward
secrecy, while offering *some* backward compatibility. Old clients which
rely on insecure and deprecated RC4 or DES-based ciphers (like Internet
Explorer 6) aren't able to complete the handshake with the default
configuration. If you absolutely must support these clients, the
[TLS recommendations] may offer a compatible cipher suite. For more details
on the format, see the [OpenSSL cipher list format documentation].

- `ecdhCurve`: A string describing a named curve to use for ECDH key agreement
or false to disable ECDH.
Expand All @@ -212,7 +203,7 @@ automatically set as a listener for the [secureConnection][] event. The
times out.

- `honorCipherOrder` : When choosing a cipher, use the server's preferences
instead of the client preferences.
instead of the client preferences. Default: `true`.

Although, this option is disabled by default, it is *recommended* that you
use this option in conjunction with the `ciphers` option to mitigate
Expand Down Expand Up @@ -853,5 +844,6 @@ The numeric representation of the local port.
[ECDHE]: https://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman
[asn1.js]: http://npmjs.org/package/asn1.js
[OCSP request]: http://en.wikipedia.org/wiki/OCSP_stapling
[TLS recommendations]: https://wiki.mozilla.org/Security/Server_Side_TLS
[SSL_CTX_set_options]: https://www.openssl.org/docs/ssl/SSL_CTX_set_options.html
[CVE-2014-3566]: https://access.redhat.com/articles/1232123
6 changes: 3 additions & 3 deletions lib/_tls_wrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -735,10 +735,10 @@ Server.prototype.setOptions = function(options) {
secureOptions |= constants.SSL_OP_CIPHER_SERVER_PREFERENCE;
}

if (options.honorCipherOrder)
this.honorCipherOrder = true;
if (options.honorCipherOrder !== undefined)
this.honorCipherOrder = !!options.honorCipherOrder;
else
this.honorCipherOrder = false;
this.honorCipherOrder = true;

this.secureOptions = secureOptions;

Expand Down
23 changes: 18 additions & 5 deletions lib/tls.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,24 @@ exports.CLIENT_RENEG_WINDOW = 600;

exports.SLAB_BUFFER_SIZE = 10 * 1024 * 1024;

exports.DEFAULT_CIPHERS =
// TLS 1.2
'ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:AES128-GCM-SHA256:' +
// TLS 1.0
'RC4:HIGH:!MD5:!aNULL';
exports.DEFAULT_CIPHERS = [
'ECDHE-RSA-AES256-SHA384',
'DHE-RSA-AES256-SHA384',
'ECDHE-RSA-AES256-SHA256',
'DHE-RSA-AES256-SHA256',
'ECDHE-RSA-AES128-SHA256',
'DHE-RSA-AES128-SHA256',
'HIGH',
'!aNULL',
'!eNULL',
'!EXPORT',
'!DES',
'!RC4',
'!MD5',
'!PSK',
'!SRP',
'!CAMELLIA'
].join(':');

exports.DEFAULT_ECDH_CURVE = 'prime256v1';

Expand Down
1 change: 1 addition & 0 deletions test/simple/test-tls-dhe.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ function test(keylen, expectedCipher, cb) {
var options = {
key: key,
cert: cert,
ciphers: ciphers,
dhparam: loadDHParam(keylen)
};

Expand Down
2 changes: 1 addition & 1 deletion test/simple/test-tls-getcipher.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ server.listen(common.PORT, '127.0.0.1', function() {
rejectUnauthorized: false
}, function() {
var cipher = client.getCipher();
assert.equal(cipher.name, cipher_list[0]);
assert.equal(cipher.name, cipher_list[1]);
assert(cipher_version_pattern.test(cipher.version));
client.end();
server.close();
Expand Down

0 comments on commit 1b1fe53

Please sign in to comment.