State of the Keybase.io website

Date

Tags
#rants

Disclaimer

Two days ago, I launched Keyoxide.org which provides a few similar functions as Keybase.io but in an Open Source package. I've been wanting to write this post for a while but felt it could be perceived as disingenuous if posted before making my own project public. Therefore, I post this now.

TLDR

The Keybase.io website uses non-optimized resources resulting in a slow pageload and 5+ year old versions of libraries with known and public security vulnerabilities.

The Keybase.io website

I have opinions about the Keybase service, but this post is not about that. This is about the facts behind their website, Keybase.io and more specifically their encrypt page, the one you use to encrypt private and confidential messages.

When you load that specific page, make sure to load it in a private session or window to eliminate cached resources. What do you notice?

It is slow. Really slow. I noticed so too and decided to run a Webpagetest (link to result). Out of three runs, we analyze only the median run (so not the best one, not the worst one).

Keybase encrypt Webpagetest overview
keybase.io/encrypt

The content loaded

It takes 6.25 seconds to fully load the 2.9 megabytes that are used on this page. That is hefty for a page that is essentially a single form. I mean, look at it:

Keybase encrypt page
Why 2.9 megabytes?

That's a regular web form. What could possibly be 2.9 megabytes? The javascript?

Webpagetest run 1 overview
How many requests? How many bytes?

Most requests are fonts. That makes sense. Earlier, we saw the page only makes 12 requests, so I could imagine a few of those being several fonts files. Fortunately, fonts are only 6.5% of the bytes loaded, so we'll forgive them.

90 percent of the bytes are due to javascript and images‽ That's 2.6 megabytes for a form! What images?

Javascript and image(s)

Let's grab the waterfall and see what is going on:

Webpagetest run 1 waterfall
Run 1 waterfall

At two points in time, the loading of the website stalls. The first stall is 2.6 seconds for the file sitewide-js.js. The second stall is 2.5 seconds for the file footprints_transp.png. Let's go.

sitewide-js.js

This file is 4.7 megabytes raw and 1.2 megabytes gzipped. Let us look at a random excerpt:

Javascript excerpt
Javascript excerpt

This is not really optimized for performance: one could choose to minimize the javascript. Allow me to use @node-minify/cli.

JS_Parse_Error [SyntaxError]: Unexpected token: name «syms», expected: punc «;»

Hmm… Let's remove that one line which simply initializes a variable (only fix I could find). I can no longer guarantee it works but let's assume it does.

Old version: 4.7 megabytes raw and 1.2 megabytes gzipped.
New version: 2.5 megabytes raw and 0.7 megabytes gzipped.

First win!

Well, I need to specify one thing: the website loads a gzipped version of the original file at a size of 1.23 megabytes. When I gzip it on my local machine, the original file even becomes 1 megabytes. I don't know what causes this discrepancy, but while we were able to reduce the raw files by 2.2 megabytes, the reduction could only become 0.3 megabytes once gzipped (on my machine™).

footprints_transp.png

Have you found the image yet? It's the little image at the bottom of the dog (?) following footprints. Cute :)

Footprints image
Footprints image

Dimensions on page: 330 x 90 pixels
Dimensions of file: 2836 x 770 pixels

That's only 8.6 times larger than it needs to be. The bigger crime is the size: 1.4 megabytes. Which is 50% of the website. You guessed it. This could be better.

Using imagecompressor.com, I can compress this full-sized image down to 398 kilobytes (reduction of 71%). And I'm even allowing the full 256 colors. And the dimensions are still 8.6 times larger than they need to be.

Optimizing the compression and the image dimensions could yield even better results. I'm not going to bother. The devs didn't either.

Still, second win!

Anything else we can learn?

The source code contains this:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                              K E Y   B A S E

                            crypto for everyone

                        because no one we know ever
                      seems to have a public key. :-(

     No Google Analytics or other 3rd party hosted script tags on Keybase.

     And this has the added bonus that we'll never be able to serve ad code.

                                    \o/  \o/
                                  keybase team

  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I like it when devs get creative. The third paragraph is a bit alienating, but that's my opinion.

Anything else? Given that this is all cryptography related, maybe some security related issues?

Security

Webpagetest security score
Webpagetest security score

I've ran quite a few webpagetests on different website, but a 0 security score is new to me. What does that even mean?

Well, it turns out that the entire website is built using the following libraries:

Besides the obvious aging, these libraries account for a total of six known and public security vulnerabilities, including cross-site scripting, prototype pollution and regular expression denial of service. All six security vulnerabilities have remediations.

Let the bootstrap v3.3.5 announcement be a painful reminder: this is pushing it.

Wrapping up

This should give a nice overview of what could go wrong with a non-optimized and aging website. This could happen to any website. But this is Keybase, the company that promises "secure messaging and file-sharing". The same company that got $10.8 million in a Serie A funding. The same company that won't allow us to see their server code.

To paint a full and fair picture, there has been an audit of the Keybase protocol [PDF] which states that:

[...] there were weaknesses in the Keybase implementation; these were quickly fixed.

The audit didn't include the website. I'll just end with another quote from the same audit:

Another common theme was the presence of legacy code. [...]
This does not necessarily imply that legacy code is insecure, but complexity and security are intertwined – every new piece of code may contain a security vulnerability, and more code correlates with more risk.