Add post
143
content/blog/2020/07/2020-07-03--keybase-website.md
Normal file
@ -0,0 +1,143 @@
|
||||
---
|
||||
title: "State of the Keybase website"
|
||||
author: Yarmo Mackenbach
|
||||
slug: keybase-website
|
||||
date: "2020-07-03 14:00:00"
|
||||
published: true
|
||||
---
|
||||
|
||||
## Disclaimer
|
||||
|
||||
Two days ago, I launched [Keyoxide.org](https://keyoxide.org) which provides a few similar functions as [Keybase.io](https://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.
|
||||
|
||||
## 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](https://keybase.io) and more specifically their [encrypt](https://keybase.io/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)](https://www.webpagetest.org/result/200627_0Q_044080ef3ab8a678721658c90d2f4706/). Out of three runs, we analyze only the median run (so not the best one, not the worst one).
|
||||
|
||||

|
||||
*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:
|
||||
|
||||

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

|
||||
*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](https://www.webpagetest.org/result/200627_0Q_044080ef3ab8a678721658c90d2f4706/1/details/#waterfall_view_step1) and see what is going on:
|
||||
|
||||

|
||||
*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*
|
||||
|
||||
Content aside, 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*
|
||||
|
||||
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](https://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 sure.
|
||||
|
||||
Anything else? Given that this is all cryptography related, maybe some security related issues?
|
||||
|
||||
## Security
|
||||
|
||||

|
||||
*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](https://snyk.io/test/website-scanner/?test=200627_0Q_044080ef3ab8a678721658c90d2f4706) that the entire website is built using the following libraries:
|
||||
|
||||
- jquery v1.11.3 (from [april 2015](https://blog.jquery.com/2015/04/28/jquery-1-11-3-and-2-1-4-released-ios-fail-safe-edition/))
|
||||
- bootstrap v3.3.5 (from [june 2015](https://blog.getbootstrap.com/2015/06/15/bootstrap-3-3-5-released/))
|
||||
- moment v2.7.0 (from [june 2014](https://github.com/moment/moment/releases/tag/2.7.0))
|
||||
|
||||
Besides the obvious aging, these libraries account for a total of six known and public security vulnerabilities, including [cross-site scripting](https://snyk.io/vuln/SNYK-JS-BOOTSTRAP-72890), [prototype pollution](https://snyk.io/vuln/SNYK-JS-JQUERY-174006) and [regular expression denial of service](https://snyk.io/vuln/npm:moment:20161019). All six security vulnerabilities have remediations.
|
||||
|
||||
Let the [bootstrap v3.3.5 announcement](https://blog.getbootstrap.com/2015/06/15/bootstrap-3-3-5-released/) 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](https://www.crunchbase.com/organization/keybase). The same company that [won't allow us to see their server code](https://github.com/keybase/client/issues/24105).
|
||||
|
||||
To paint a full and fair picture, there has been an [audit of the Keybase protocol [PDF]](https://keybase.io/docs-assets/blog/NCC_Group_Keybase_KB2018_Public_Report_2019-02-27_v1.3.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.
|
||||
BIN
content/img/keybase_encrypt.png
Normal file
|
After Width: | Height: | Size: 115 KiB |
BIN
content/img/keybase_encrypt__img.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
content/img/keybase_encrypt__js_excerpt.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
content/img/keybase_encrypt__security.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
content/img/keybase_encrypt__wpt_1.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
BIN
content/img/keybase_encrypt__wpt_1_waterfall.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
content/img/keybase_encrypt__wpt_overview.png
Normal file
|
After Width: | Height: | Size: 24 KiB |