There have been several
attacks on various SSL/TLS configurations the last few years so configuring
SSL/TLS correctly is a slippery slope. To keep up to date on the current state of affairs
I strongly recommend you keep an eye on SSL Labs and follow @ivanristic on Twitter. SSL Labs provides a SSL
server test that quickly assesses your servers’ current configuration and
you’ll find a series of blog posts by Ivan Ristic that go into detail on the various SSL/TLS
issues.
As I was finishing this
blog post, a brilliant example of poor TLS configuration showed up in my
Twitter timeline:

I did an SSL Labs scan
of the governmental site, and it reported "HTTP server signature:
Microsoft-IIS/7.5" so it was almost certainly running on WS 2008 R2 servers with
default TLS configuration (we’ll get to those in a bit). The incident is a
brilliant example because it shows two out of three outcomes based on how you configure
TLS. First, you might be called out for running with an insecure configuration
and not protecting your users. Second, you can't enable only the latest and
most secure protocol versions, as you would break your site for a large number
of users. TLS configuration is all about finding the right balance — the third
and preferred outcome.
Windows Server and SSL/TLS
These days we’re
running WS 2008 or WS 2012 and the cryptographic support has improved a lot over
previous versions. Here are the important differences between the Windows
Server versions:
- WS 2003 had SSL 2.0/3.0 and TLS 1.0 enabled by default. The default installation did not support AES ciphers – but support could be added through a hotfix.
- WS 2008 also had SSL 2.0/3.0 and TLS 1.0 enabled by default, but improved the cryptographic support with new AES cipher suites.
- WS 2008 R2 introduced TLS 1.1 and TLS 1.2, but they were disabled by default.
- WS 2012 takes us a step further with TLS 1.2 enabled by default.
As the list shows, supported
versions are one thing, enabled versions are another. To complicate things further
there’s a set of supported cipher suites for each protocol version, i.e.
combinations of key exchange, encryption and hash algorithms used to secure the
channel. We need to enable both secure protocol versions and secure cipher
suites to secure the connections to our servers.
If you’re running a
web server, IIS relies on the Secure Channel (Schannel) security support provider included
in the Windows OS to handle SSL/TLS connections. You’ll find the default cipher
suites and their preferred order documented in Cipher Suites in Schannel. Schannel is configurable through a number of registry settings.
Current TLS recommendations
The SSL Labs TLS
configuration guidance was updated recently (v1.3), introducing new
recommendations. Here’s the changelog:
- Recommend replacing 1024-bit certificates straight away.
- Recommend against supporting SSL v3.
- Remove the recommendation to use RC4 to mitigate the BEAST attack server-side.
- Recommend that RC4 is disabled.
- Recommend that 3DES is disabled in the near future.
- Warn about the CRIME attack variations (TIME and BREACH).
- Recommend supporting Forward Secrecy.
- Add discussion of ECDSA certificates.
We’ll briefly discuss
each recommendation before we look into default Windows Server TLS
configurations.
Replacing 1024-bit certificates
The new recommendation
is to use certificates with 2048-bit RSA keys. Google announced in May that they were switching to 2048 bit keys in
their certificates, and are now using new certificates on e.g. google.com.
There are also upcoming changes to Google Chrome's
certificate handling. In
early 2014 we can expect Chrome to start warning users about certificates that
fit certain criteria: if they have a key length < 2048 and are valid from or
after 1. July 2012 or expire after 31. December 2013. The Microsoft Security Development
Lifecycle (SDL) Process
Guidance - Version 5.2 requires that you use 2048-bit or better RSA keys, and
it’s also a requirement for SSL certificates in Windows Azure. Consequently, this recommendation is in
practice already a requirement, so make sure you generate new 2048 bit keys
when ordering new certificates or renewing old ones.
Disable SSL 3
Clients that only
support SSL 3 are (finally) dying off, so disabling this version will only break
the internet for the tiny fraction of users that still run ancient software such as IE 6 on Windows XP. Google announced three years ago that they would start phasing out support for IE
6, and many other sites have followed. Note that Microsoft still supports
Windows XP (until April 8, 2014), but a patched Windows XP will be running IE
8 and support TLS 1.0. Consequently, it should be safe to disable SSL 3.
Disable RC 4 ciphers
The RC4 cipher is now considered insecure, and it is recommended to drop support for it.
The recommendation might well become a formal requirement in the future. A
recent Internet-Draft, Prohibiting RC4 cipher suites, requires that TLS clients and servers drop
support for RC4 cipher suites. RC4 was the
recommended mitigation to the BEAST attack, but recent browsers have
implemented client-side mitigations for this attack (except Safari). Weighing
one risk against the other, it makes sense to disable RC4 since it affects all
clients. To learn more about the RC4 vs BEAST tradeoff, see Is BEAST still a threat?
Disable 3DES
The recommendation to
disable 3DES is a bit more problematic. Windows XP does not support the AES cipher suites added for TLS 1.0, and
when we’ve sifted out the insecure cipher suites (including RC4) supported by
XP we’re left with 3DES as our only option. Disabling 3DES means we’d break our
site for XP/IE8 users — that could be devastating considering XP still holds a 20% market share. So unfortunately, we’ll have have to stick
with 3DES for now.
CRIME attack variations (TIME and
BREACH)
The CRIME attack showed how a middleperson attack could extract
information from the encrypted traffic to sites that had TLS compression
enabled. Schannel does not support TLS compression, so CRIME is not a threat
for applications running under IIS. Earlier this year two related attacks emerged,
TIME and BREACH, both targeting compressed HTTP responses. It
is unclear how we can mitigate these attacks in a practical manner, but you’ll
find a discussion on how e.g. CSRF tokens can be protected in Defending against the BREACH Attack. We can’t mitigate the attack through TLS
configuration (which is the topic of this post), so we’ll move on to the next
recommendation.
Forward secrecy
Forward secrecy refers
to how session keys are set up for a TLS session. In the TLS cipher suites that
are typically used (such as TLS_RSA_*), session keys are protected under the
RSA key found in the server’s certificate. If someone records the encrypted
traffic to the server and at some later point gets access to the server’s key,
all recorded sessions can be decrypted.
Cipher suites that offer
forward secrecy improves the situation by employing temporary keys during the
TLS key exchange. These keys are thrown away after the session keys have been
generated. This protects each session under separate, temporary session keys.
An adversary would have to crack the session keys to learn the contents of a recorded
session — and would have to repeat the process for each session. The cipher
suites that offer forward secrecy are the ones named TLS_DHE_*and TLS_ECDHE_*.
We won’t go in to further details here, but you’ll find a nice explanation in Deploying Forward Secrecy. Google started rolling out forward secrecy two years ago, and other big players are following their lead. We should all follow their example
to better protect our users.
ECDSA certificates
The final SSL Labs recommendation
is to use ECDSA certificates. These certificates contain an ECDSA public
key instead of an RSA key. ECDSA keys rely on a different type of math based on
elliptic curves (EC), yielding a better keylength/security ratio than RSA. This
means we can use smaller keys, but still achieve the same level of security.
Unfortunately, ECDSA certificates aren’t quite mainstream yet. I’ve tried to
find a CA that would issue ECDSA certificates, but no luck there (yet). When
these certificates become more generally available, we should seize the
opportunity when current certificates expire and make the switch. Note that if
you’re running your own CA you could set it up to issue ECDSA certificates.
That was a brief
overview of the new SSL Labs recommendations, next we’ll look at the default
configuration for recent Windows Server versions and see how they fare against
the recommendations.
The default state of affairs
To give a snapshot of
what Windows Server offers out-of-the-box in terms of SSL/TLS, I’ve collected
some data based on the Virtual Machines (VMs) and web role instances that are
available through Windows Azure today. If you spin up a new VM on Windows Azure
you can choose between WS 2008 R2 SP1 and WS 2012 Datacenter (or a bunch of Linux
distros which is really cool). For web roles you can choose between Guest OS family 1-3. Microsoft is retiring support for version
1 (WS 2008) so we’ll look at version 2 (WS 2008 R2) and version 3 (WS 2012). Guest OS
family 2 is the default for new cloud service projects in Visual Studio 2012
with the latest Azure SDK. You can manually change the OS family version to 3
in the ServiceConfiguration file in your cloud project to get the latest version.
Windows Server 2008 R2 SP1
The WS 2008 VM flunks the
SSL Labs test.
The server scores 0 on
“Protocol support” since it supports SSL 2.0, and there’s also a note that SSL
2 support will give you the grade F. Due to laziness I set the server up with a
self signed certificate which also gives it a zero score on the certificate.
We also note that SSL
3 is enabled, and that TLS 1.1/1.2 are disabled in the next figure.
SSL Labs warns about
two insecure SSL 2.0 cipher suites and we see that RC4 is enabled. There are
two cipher suites offering forward secrecy (TLS_ECDHE_*), but they’re placed
towards the end of the list. This means that they won’t be selected in practice
since browsers support at least one of the suites with higher priority, i.e. unless
you disable them by hand in your browser configuration.
The picture could have
been much prettier as WS 2008 R2 supports TLS 1.1/1.2, but unfortunately these
versions are disabled by default. The decision to enable SSL 2 by default is
questionable to say the least. SSL 2 was released in 1995 but a number of
security flaws led to a redesign and the release of SSL 3 in 1996.
If you’re running WS 2008 servers you don’t have much of a choice — you have to harden the TLS configuration! I assume this was the problem for the governmental website mentioned earlier.
If you’re running WS 2008 servers you don’t have much of a choice — you have to harden the TLS configuration! I assume this was the problem for the governmental website mentioned earlier.
Windows Server 2008 R2 Azure web role (Guest OS family 2)
Next we’ll have a look
at the WS 2008 R2 based web roles, this time I’ve also installed a trusted
certificate.
SSL 2.0 is disabled
for OS family 2 instances and this does wonders for the score. We still get a
warning that TLS 1.2 is unsupported.
The SSL 2 ciphers are
now gone, apart from that we see that the list is identical to that of the WS 2008 R2 VM. Even though this configuration is an improvement over the default WS 2008
configuration, it still needs tweaking to meet the SSL Labs recommendations.
Windows Server 2012 / Azure Guest OS family 3
The TLS configuration
is identical for WS 2012 VM’s and OS family 3 Azure instances, so we’ll just refer to them as WS 2012. The
default configuration gives us a better score on protocol support since WS 2012
supports TLS 1.2 out-of-the-box.
In addition to TLS 1.2
support, we also get three new SHA256 cipher suites.
Things are starting to
look better, but forward secrecy ciphers suites still aren’t prioritized and SSL
3 is still enabled along with the RC4 cipher. For the WS 2012 there’s also room for improvement.
Now that we’ve covered
the current state of affairs, let’s turn our attention to how we can harden the
TLS configuration.
Configuring Schannel
You might recall that
you can configure enabled protocol versions and cipher suites in Schannel through a number of registry settings. The preferred order and support for cipher
suites is configurable through group policy (and native code). Tweaking the registry can
be cumbersome so you’ll find various clients that can help you manage Schannel
configuration. Unfortunately, configuring TLS by hand doesn’t work very well
for Azure applications. You’ll need to do it in an automated fashion since Azure
instances can be re-provisioned at any time. That brings us to my announcement!
Announcing NWebsec.AzureStartupTasks
The very first version
of NWebsec.AzureStartupTasks includes an Azure startup task that configures Schannel according to the
recommendations from SSL Labs. The scripts are available through a NuGet package for easy installation in an ASP.NET project. You’ll need to copy a few
lines of config from the included ReadMe file to the ServiceDefinition.csdef in
your cloud service project and you’ll be all set!
You can download the
scripts from the project website and add them to a project by hand if you don’t
have the option of using NuGet packages. The scripts also work stand-alone if
you want to run them by hand on a Windows Server. Refer to the Install.txt for
instructions.
The TLS configuration
script requires PowerShell version 2 and so works for WS 2008 R2 (OS family 2) and
later. It disables SSL 2.0 and 3.0, and makes sure TLS 1.0/1.1/1.2 are enabled.
I’ve taken the default list of cipher suites and modified it slightly. I’ve
moved cipher suites that offer forward secrecy to the top of the list and RC4 suites
are excluded, but the 3DES suite is still enabled to not break the internet for
XP/IE8 users. I’ve also added two newer TLS 1.2 AES GCM suites (but they
require an ECDSA certificate). For reference, here’s the complete list of
enabled cipher suites (in version 1.0):
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P384
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_P256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P384
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P384
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_P384
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
TLS_DHE_DSS_WITH_AES_256_CBC_SHA
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_3DES_EDE_CBC_SHA
I’ll update the
package in accordance with new recommendations from SSL Labs. This is what the SSL
test results will look like (at the time of writing) with this configuration:
Still all green, but we’ve
turned the score on protocol support up a notch. Under “Cipher suites”, the
forward secrecy suites are now preferred.
Things are looking a
whole lot better! Since we’ve brought the protocol versions and supported
cipher suites in line with the current SSL Labs recommendations, we’ll look at the
some of the “Protocol Details” in the test result.
Things are mostly looking
good, but there’s a warning about the BEAST attack. Unfortunately, at this
point we can’t win. One countermeasure to thwart BEAST is to
prioritize the now-considered-insecure RC4 cipher. Another option is to disable
TLS 1.0 — which would break the site in most browsers. We’ll simply have to
live with the risk for now and hope that Apple implements the client side BEAST
countermeasure found in other browsers (and that all browsers move fast to
implement TLS 1.2).
There’s also a warning
about session resumption. This is due to the Azure load balancer and non-sticky
sessions. If you run a single instance in your cloud service, session
resumption will turn green since all connections will hit the same instance.
Session tickets, aka RFC 5077 (TLS Session Resumption without Server-Side
State), are underway in Windows Server 2012 R2 Preview and can solve the problem with non-sticky
sessions. As a side note, key management for session tickets must be
implemented with great care to avoid breaking forward secrecy. For more details,
refer to How to botch TLS forward secrecy. Fortunately, it’s Microsoft’s problem to get
this right.
OCSP stapling has been
enabled by default since WS 2008. It improves performance and users' privacy.
Strict Transport
Security is a HTTP security header that instructs web browsers to use HTTPS
only when communicating with your web site. You’ll find more details in my blog
post on Security through HTTP response
headers. The header
must be set in your web application, the NWebsec security
library helps you set this and several other important security headers.
Wrapping up
The default TLS configuration
in recent Windows Server versions needs hardening to meet recent
recommendations. You can easily test your site at SSL Labs to see how it fares
— note that anyone can do this for your site (recall the governmental website)
so you’d better harden that configuration!
The NWebsec.AzureStartupTasks NuGet package provides scripts that help you bring the TLS configuration in order for Azure
applications. The scripts are available for download so you can use them on other servers, and you can easily
tweak them to your needs. The NWebsec demo site will always be using the latest version of the package, feel free to put it to the SSL Labs test (select the www.nwebsec.com entry). Follow @NWebsec on Twitter to keep up with new releases.
We’ve been focusing on
TLS server side, but if you’re curious about how your browser is configured you
should also check out the SSL Client Test. It takes two to tango, both the browser and
server needs to support secure protocol versions and cipher suites.
Happy TLS hardening!
Final note
Scanning a WS 2012 through
SSL Labs generated 84 errors in the system event log, these two errors showed
up pairwise:
An TLS 1.2 connection request was received from a remote client application, but none of the cipher suites supported by the client application are supported by the server. The SSL connection request has failed.
And
A fatal alert was generated and sent to the remote endpoint. This may result in termination of the connection. The TLS protocol defined fatal error code is 40. The Windows SChannel error state is 1205.
If your event log
fills up with these, you’ve probably been SSL Lab’ed!










1,034 comments:
«Oldest ‹Older 1401 – 1034 of 1034Post a Comment