netsekure rng

random noise generator

Privilege separation in WordPress

A recent retweet by Jeremiah Grossman got me thinking. Why doesn’t WordPress implement privilege separation in their blog engine? After all it is fairly simple and can be implemented in a few lines of code.

I don’t know the reason to be honest, as this is one of the basic rules of security. Few months ago I did it for my blog, since I don’t see a valid reason why anyone coming across the Internet needs to have “drop table” privilege or similar on my blog’s database. I looked around for a convenient mailing list to post my idea to and unfortunately I couldn’t find one, so I gave up on trying to message the idea directly to WordPress developers, but now I’ve decided to at least post it for people to take advantage of it.

Here is what I have done that should give you basic level of privilege separation with just a simple WordPress tweak.
First, you need to have the two separate database users - admin and public. We also need to assign the proper privileges/permissions (after all this is the main idea):

public -> db: [SELECT,INSERT]
admin -> db: [SELECT,INSERT,UPDATE,CREATE,DELETE,ALTER,DROP,INDEX,CREATE TEMPORARY TABLES,LOCK TABLES,CREATE VIEW,SHOW VIEW]

Since I have comments enabled, I had to give the public user the INSERT privilege, but at least I have taken away the 10 extra privs away from it. If you don’t allow comments on the blog, you can even remove the INSERT functionality, though I haven’t tested this one and don’t know if anything else would break.

The only other thing left to do is configure WordPress to pick the right database user. This is accomplished easily through wp-config.php:

if ( defined('WP_ADMIN') || defined('DOING_CRON') )  {
  define('DB_USER', 'admin');
  define('DB_PASSWORD', 'admin_password');
} else {
  define('DB_USER', 'public');
  define('DB_PASSWORD', 'public_password');
}

I’ve only had this customization interfere once in my almost half year since I’ve implemented it. It was during WordPress upgrade, which required a change to the database schema. In such cases, it is trivial to restore back to the default behavior for the duration of the upgrade and then go back to separate users.

I hope this helps people reduce some of the attack surface on their blogs and ideally WordPress will do this natively in the future.

Results after 30 days of (almost) no trusted CAs

Today marks the 30th day since I removed all the root certificates for trusted certificate authorities. It was an interesting one month and I’ve learned a bunch. The main takeaway from this experiment is that I don’t need 3 digit number of trusted CAs in my browser. Again, this is person specific and US centric, but the total count as of today is 10! The list of subject names and signatures follows for the ones interested in the exact list.

CN=Equifax Secure Global eBusiness CA-1, O=Equifax Secure Inc., C=US
7e784a101c8265cc2de1f16d47b440cad90a1945

OU = VeriSign Trust Network, OU = “© 1998 VeriSign, Inc. - For authorized use only”, OU = Class 3 Public Primary Certification Authority - G2, O = “VeriSign, Inc.”, C = US
85371ca6e550143dce2803471bde3a09e8f8770f

OU=Class 3 Public Primary Certification Authority, O=VeriSign, Inc., C=US
742c3192e607e424eb4549542be1bbc53e6174e2

OU=Equifax Secure Certificate Authority, O=Equifax, C=US
d23209ad23d314232174e40d7f9d62139786633a

CN=GTE CyberTrust Global Root, OU=“GTE CyberTrust Solutions, Inc.”, O=GTE Corporation, C=US
97817950d81c9670cc34d809cf794431367ef474

CN=Entrust.net Secure Server Certification Authority, OU=© 1999 Entrust.net Limited, OU=www.entrust.net/CPS incorp. by ref. (limits liab.), O=Entrust.net, C=US
99a69be61afe886b4d2b82007cb854fc317e1539

CN=AddTrust External CA Root, OU=AddTrust External TTP Network, O=AddTrust AB, C=SE
02faf3e291435468607857694df5e45b68851868

E=premium-server@thawte.com, CN=Thawte Premium Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, S=Western Cape, C=ZA
627f8d7827656399d27d7f9044c9feb3f33efa9a

OU=Go Daddy Class 2 Certification Authority, O=“The Go Daddy Group, Inc.”, C=US
2796bae63f1801e277261ba0d77770028f20eee4

CN = GlobalSign Root CA, OU = Root CA, O = GlobalSign nv-sa, C = BE
b1bc968bd4f49d622aa89a81f2150152a41d829c

The last one I’ve included for completeness, since I don’t really need it, but I had to enable it to access openssl.org over https. It is currently not trusted.

While this is a good list of certs to enable for security geeks like myself, I’m not quite sure how feasible this is today for the average user, so I wouldn’t recommend doing this to your parents' computer. Even for me it was hard to realize that application failures (such as twhirl completely stopping to work) are due to a root certificate no longer being trusted and SSL connections failing. I also had to look at the wire traffic on a few occasions where the UI would never expose the “I want to see which certificate is failing” option.

One needs to be very careful which certs are disabled. Since it is hard to troubleshoot failures that result from disabling trusted roots, reading up and getting familiar with how certificates work is a great idea. Firefox has its own certificate storage, completely separate from the OS, so messing with it is not as big of an issue, as any errors are isolated to Mozilla applications. Here are some resources for Windows (which affects IE and Chrome):

  • There is a list of mandatory certificates that Windows needs to operate, which is listed here.
  • There is a great overview of how the trusted roots certificates work on Windows and explains why people see things “change” under the hood.
  • Also, in newer versions there seem to be a lot more control on how certificates are validated and what roots are trusted.
  • The list of CAs that Windows trusts.

I hope this information is helpful to people. Feel free to ping me with questions you might have related to this small project.

How to disable trusted root certificates

As part of my testing of how many trusted root certificates I need for my day-to-day activities, I needed to ensure I don’t trust any certificate authorities. There is a great post by Nelson Bolyard to one of the security mailing lists of Mozilla, which explains why one should not delete CA certificates, but rather disable them. The main take away is that there is a big difference between the statements “I don’t know you” (if you remove the certificate) and “I know you and I don’t trust you” (disabling the certificate). Some browsers also handle these errors differently.

The different browsers store certificates differently. IE, Chrome, and I believe Safari as well (haven’t tested it) on Windows use the OS built-in certificate infrastructure, while Firefox uses its own certificate storage. As such, here are the steps you need to take for the two different cases:

IE, Chrome (Safari?)

You need to run the certmgr.msc utility (either through Start->Run/Search or from a command prompt). This will launch the UI used to manage the certificate stores in Windows for the current user.

CertMgr Certificate Stores

The “Third-Party Root Certification Authorities” stores all the trusted 3rd party CAs. You will find either a fairly small set of those if Windows hasn’t downloaded the full list, or quite a bit of them after the full list has arrived. To disable the root certificates, select the ones you want and drag them to the “Untrusted Certificates” store and drop them under the “Certificates” subfolder. This instructs the certificate infrastructure in Windows to not trust these certificates. The result is that even though you have the certificates in other stores, the operations will fail. The “Untrusted Certificates” store trumps all others, so you don’t have to worry about forgetting a certificate somewhere else.

Keep in mind that doing this in Windows will affect all programs that use SSL/TLS and certificates. I’ve broken my twitter client for example by removing all CAs from the trusted list : ).

Firefox

You will need to click on Tools->Options, select the Advanced category, select the Encryption, click View Certificates, and click on the Authorities tab. This will open up a window with all the trusted certificate authorities. For each of those, once you select it, you can click on the “Edit” button and you will see a window that looks like this:

Firefox Trusted CA

This CA is trusted for all 3 types of identification. To disable the certificate, just uncheck all the check boxes and click Ok:

Firefox Disabled CA

The result is that this certificate is no longer trusted to vouch for the identity of anything. You need to repeat the process for all the certificates you want to disable and I don’t know of an easy way to automate this. For the certificates listed as “Builtin Object Token”, Marsh Ray has tried deleting them and claims that this results in disabling them (since they are built-in and cannot be deleted) after restarting Firefox.

After you have disabled the CA certificates, you can expect SSL/TLS connections to fail if the certificate is issued by a disabled CA.

Have fun browsing with minimized attack surface : )

30 days with (almost) no trusted CAs

I’ve decided to embark on a small project to determine what is the smallest set of trusted root certificates I need in my day-to-day life. I have disabled all trusted CAs in both IE and Firefox and will enable the needed root certificates as I go. So far I’ve spent a week of this and have about 10 certificates, 3 of which were needed because I needed to pay my bills : ).

I will run in this mode for 30 days, at the end of which I will report how many root certificates I had to enable to allow me to go through life. In the meantime, I am tweeting every time I need to enable a CA along with the site that needed it.

It is a fun ride so far, so let’s see where it is going to take me.

Most common trusted root certificates

With the press coverage lately about governments being able to subvert SSL/TLS by coercing a certificate authority into issuing rogue certificates, I decided to do some data gathering in order to answer a simple question:

How many trusted roots does the average person need in their browser?

To answer the question, I wrote a small tool to collect the root cert for a list of sites and ran it on a sets of data - a mix of known SSL/TLS sites and hosts on the Alexa Top 1 Million list. So out of 350k hosts queried, I was able to collect 50812 entries. The stats are fairly interesting and somewhat expected. The number of certificate authorities that have issued more than 50 certificates for that set of data is 37.

While I was gathering the data, it became known that even Mozilla includes some root certificates that don’t have complete clarity of ownership.

My plan now is to remove most of the CA root certificates that ship in browsers. It will be informative to see what breaks and how many issues I run into. After a month or so of usage, I will post the details and hopefully it will be an easy guide as to the smallest set of trusted CAs to have and not be impacted in daily business. Granted this will be a US centric list, most international users can probably add one or two trusted roots that are for CAs issuing country specific certificates.

What follows is the list of root certificates (also available as text file) sorted with decreasing popularity. The format is “Number of issued certs | Friendly name | Subject”.

7519 | GeoTrust | OU=Equifax Secure Certificate Authority, O=Equifax, C=US
4277 | USERTrust | CN=AddTrust External CA Root, OU=AddTrust External TTP Network, O=AddTrust AB, C=SE
4007 | Go Daddy Class 2 Certification Authority | OU=Go Daddy Class 2 Certification Authority, O="The Go Daddy Group, Inc.", C=US
3701 | VeriSign Class 3 Public Primary CA | OU=Class 3 Public Primary Certification Authority, O="VeriSign, Inc.", C=US
2948 | USERTrust | CN=UTN-USERFirst-Hardware, OU=http://www.usertrust.com, O=The USERTRUST Network, L=Salt Lake City, S=UT, C=US
2649 | thawte | E=premium-server@thawte.com, CN=Thawte Premium Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, S=Western Cape, C=ZA
2077 |  | E=info@plesk.com, CN=plesk, OU=Plesk, O=Parallels, L=Herndon, S=Virginia, C=US
1898 | Equifax Secure Global eBusiness CA-1 | CN=Equifax Secure Global eBusiness CA-1, O=Equifax Secure Inc., C=US
1806 | VeriSign | OU=VeriSign Trust Network, OU="(c) 1998 VeriSign, Inc. - For authorized use only", OU=Class 3 Public Primary Certification Authority - G2, O="VeriSign, Inc.", C=US
1580 |  | E=webaster@localhost, CN=localhost, OU=none, O=none, L=Sometown, S=Someprovince, C=US
1461 |  | E=root@localhost.localdomain, CN=localhost.localdomain, OU=SomeOrganizationalUnit, O=SomeOrganization, L=SomeCity, S=SomeState, C=--
1378 | thawte | E=server-certs@thawte.com, CN=Thawte Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, S=Western Cape, C=ZA
1366 | VeriSign | CN=VeriSign Class 3 Public Primary Certification Authority - G5, OU="(c) 2006 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
1189 |  | E=info@plesk.com, CN=plesk, OU=Plesk, O="SWsoft, Inc.", L=Herndon, S=Virginia, C=US
922 | Entrust | CN=Entrust.net Secure Server Certification Authority, OU=(c) 1999 Entrust.net Limited, OU=www.entrust.net/CPS incorp. by ref. (limits liab.), O=Entrust.net, C=US
902 | GlobalSign | CN=GlobalSign Root CA, OU=Root CA, O=GlobalSign nv-sa, C=BE
783 | GTE CyberTrust Global Root | CN=GTE CyberTrust Global Root, OU="GTE CyberTrust Solutions, Inc.", O=GTE Corporation, C=US
737 | CúOúMúOúDúO | CN=COMODO Certification Authority, O=COMODO CA Limited, L=Salford, S=Greater Manchester, C=GB
692 |  | E=ca@snakeoil.dom, CN=Snake Oil CA, OU=Certificate Authority, O="Snake Oil, Ltd", L=Snake Town, S=Snake Desert, C=XY
461 | DigiCert | CN=DigiCert High Assurance EV Root CA, OU=www.digicert.com, O=DigiCert Inc, C=US
394 | Starfield Class 2 Certification Authority | OU=Starfield Class 2 Certification Authority, O="Starfield Technologies, Inc.", C=US
264 |  | E=hostmaster@ispgateway.de, CN=webserver.ispgateway.de, O=ispgateway, L=Kempten, S=Bayern, C=DE
257 |  | E=info@parallels.com, CN=plesk, OU=Plesk, O="Parallels, Inc.", L=Herndon, S=Virginia, C=US
208 | Entrust (2048) | CN=Entrust.net Certification Authority (2048), OU=(c) 1999 Entrust.net Limited, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), O=Entrust.net
198 | Trustwave | CN=SecureTrust CA, O=SecureTrust Corporation, C=US
168 |  | E=sslsign@lxlabs.com, CN=*.lxlabs.com, OU=web, O=lxlabs, L=WA, S=WA, C=IN
143 | thawte | CN=thawte Primary Root CA, OU="(c) 2006 thawte, Inc. - For authorized use only", OU=Certification Services Division, O="thawte, Inc.", C=US
101 |  | E=info@confixx.com, CN=confixx, OU=Confixx, O="SWsoft, Inc.", L=Herndon, S=Virginia, C=US
98 | StartCom Certification Authority | CN=StartCom Certification Authority, OU=Secure Digital Certificate Signing, O=StartCom Ltd., C=IL
92 |  | E=support@cacert.org, CN=CA Cert Signing Authority, OU=http://www.cacert.org, O=Root CA
87 | USERTrust | CN=UTN - DATACorp SGC, OU=http://www.usertrust.com, O=The USERTRUST Network, L=Salt Lake City, S=UT, C=US
71 | VeriSign | OU=Secure Server Certification Authority, O="RSA Data Security, Inc.", C=US
70 | Starfield Technologies | E=info@valicert.com, CN=http://www.valicert.com/, OU=ValiCert Class 2 Policy Validation Authority, O="ValiCert, Inc.", L=ValiCert Validation Network
64 |  | CN=localhost, OU=For testing purposes only, O=Apache HTTP Server
63 |  | E=admin@suresupport.com, CN=suresupport.com, OU=suresupport.com, O=suresupport.com, L=US, S=US, C=US
62 | SECOM Trust Systems CO LTD | OU=Security Communication RootCA1, O=SECOM Trust.net, C=JP
61 | Network Solutions | CN=Network Solutions Certificate Authority, O=Network Solutions L.L.C., C=US

TLS overhead

Every so often I get the question – “What is the overhead incurred by using TLS?”. Strangely enough, I couldn’t find a straight answer by doing some searching on the web, so let’s explore the answer. The TLS handshake has multiple variations, but let’s pick the most common one – anonymous client and authenticated server (the connections browsers use most of the time). As per the TLS standard the handshake looks as follows:

      Client                                               Server

      ClientHello                  -------->
                                                      ServerHello
                                                      Certificate
                                   <--------      ServerHelloDone
      ClientKeyExchange
      [ChangeCipherSpec]
      Finished                     -------->
                                               [ChangeCipherSpec]
                                   <--------             Finished
      Application Data             <------->     Application Data

One thing to keep in mind that will influence the calculation is the variable size of most of the messages. The variable nature will not allow to calculate a precise value, but taking some reasonable average values for the variable fields, one can get a good approximation of the overhead. Now, let’s go through each of the messages and consider their sizes.

  • ClientHello – the average size of initial client hello is about 160 to 170 bytes. It will vary based on the number of ciphersuites sent by the client as well as how many TLS ClientHello extensions are present. If session resumption is used, another 32 bytes need to be added for the Session ID field.
  • ServerHello – this message is a bit more static than the ClientHello, but still variable size due to TLS extensions. The average size is 70 to 75 bytes.
  • Certificate – this message is the one that varies the most in size between different servers. The message carries the certificate of the server, as well as all intermediate issuer certificates in the certificate chain (minus the root cert). Since certificate sizes vary quite a bit based on the parameters and keys used, I would use an average of 1500 bytes per certificate (self-signed certificates can be as small as 800 bytes). The other varying factor is the length of the certificate chain up to the root certificate. To be on the more conservative side of what is on the web, let’s assume 4 certificates in the chain. Overall this gives us about 6k for this message.
  • ClientKeyExchange – let’s assume again the most widely used case – RSA server certificate. This corresponds to size of 130 bytes for this message.
  • ChangeCipherSpec – fixed size of 1 (technically not a handshake message)
  • Finished – depending whether SSLv3 is used or TLS, the size varies quite a bit – 36 and 12 bytes respectively. Most implementations these days support TLSv1.0 at least, so let’s assume TLS will be used and therefore the size will be 12 bytes.

Now that we have an average size of each message exchanged, we can calculate the average handshake size. One has to keep in mind that messages exchanged have TLS Record header for each record sent (5 bytes), as well as TLS Handshake header (4 bytes). The most common case can be simplified such that each arrow in the handshake diagram is a TLS Record, so we have 4 Records exchanged for total of 20 bytes. Each message has the handshake header (except the ChangeCipherSpec one), so we have 7 times the Handshake header for total of 28 bytes.

The total overhead to establish a new TLS session comes to about 6.5k bytes on average (20 + 28 + 170 + 75 + 6000 + 130 + 2*1 + 2*12 = 6449).

TLS sessions once established can also be resumed. In the session resumption, some of the messages are omitted and the handshake looks as follows:

      Client                                               Server

      ClientHello                  -------->
                                                      ServerHello
                                               [ChangeCipherSpec]
                                   <--------             Finished
      [ChangeCipherSpec]
      Finished                     -------->
      Application Data             <------->     Application Data

The main difference here is that the ClientHello message will contain extra 32 bytes for the session ID it wants to resume.

The total overhead to resume an existing TLS session comes to about 330 bytes on average (15 + 16 + 202 + 75 + 2*1 + 2*12 =332 ).

Now let’s look at the overhead on the wire for the encrypted application data. The data is carried in TLS Records over the wire, so there are 5 bytes of header. Since data is encrypted and integrity protected, there is additional overhead that is incurred. Let’s assume that the ciphersuite negotiated between the client and the server is TLS_RSA_WITH_AES_128_CBC_SHA, which is mandatory for TLS1.2 and hopefully will be commonly negotiated going forward. Since AES is a block cipher, it requires the data to be sized in multiple of the block size. TLS 1.0 defines the encrypted data with block cipher as:

    block-ciphered struct {
        opaque content[TLSCompressed.length];
        opaque MAC[CipherSpec.hash_size];
        uint8 padding[GenericBlockCipher.padding_length];
        uint8 padding_length;
    } GenericBlockCipher;

Since most implementations don’t use compression, we can assume the data is the same size. The MAC in this case is computed using SHA1, so the size will be 20 bytes. AES128 has a block size of 16 bytes, so the maximum padding we can add to the data will be 15 bytes.

The total overhead of the encrypted data is about 40 bytes (20 + 15 + 5).

It is easy to modify the above calculations to reflect more precisely the specifics of an environment, so this should be considered a basis for TLS overhead and not the authoritative answer to the question posed.

TLS Renegotiation MITM fix is now official

As of Feb 12th, the solution for the TLS renegotiation man-in-the-middle attack is an official IETF standard:

http://tools.ietf.org/html/rfc5746

I’m super happy and excited as this is the first RFC I am a co-author of and it fixes a major problem with one of the most widely used security protocols. Now let’s hope it will get quickly implemented, deployed, and eventually enforced.