On computers, we have a big challenge where we know that we can get way more user growth via web browser deployments of the Blockstack app than we can via native desktop deployments. That’s because of the large amount of friction that’s involved.
At the same time, we know that websites have massive security challenges that aren’t faced by native desktop applications. Historically, these issues have been so large for crypto startups that web deployments have been a non-starter. That’s because the cost of a website hijacking manifests itself in terms of stolen private keys. And this translates to an unacceptably large risk.
The hijacking of the website generally comes down to vulnerabilities around the accounts that control the app server and the domain name resolution of the site. If the server or the domain name can be hijacked, the user can be served malicious code that scoops up the user’s private keys and steals everything belonging to the user.
A similar risk applies to native desktop and mobile applications as well, as all native app updates are controlled centrally by update servers. However there are additional safeguards that make native apps more secure. First, every app is served as a bundle that can be hashed / integrity checked and then published through a platform that ensures it distributes the same bundle to every user. Second, on certain platforms the user has to explicitly authorize updates, which means that if there’s a window during which the update server gets hijacked, there’s still a way to recover and save most users before they authorize and download the malicious update.
Here I’d like to explore an interesting idea that allows a web app to (1) effectively behave as a native desktop app and (2) get the security benefits of a native desktop app, while still existing inside of a web page.
The approach involves a few steps.
Step 1: Thanks to the “Cache-Control” HTTP headers, we can instruct the browser to cache the web page for up to one year. That means that the user will not be served updates until the cache expires or the user performs a hard refresh. This can help us avoid attacks on app servers and DNS servers. Of course, you’re probably thinking that now the app cannot be easily updated, so what is the point. That brings us to the next step.
Step 2: We can modify the app so that it has an outer frame and an inner app. The outer frame is extremely simple and only needs to be updated once a year. All it does is (1) embed another app inside of it (2) check the SHA-256 integrity tag of the index.html
file against a set of blockchain nodes that can report on the latest hash of the updated app. The frame only includes an indicator that the app is fresh or stale (green or yellow dot) and a button that allows the user to refresh the app inside the frame if it is stale.
Note that in the rare instance that the outer frame needs to be modified, the user could be instructed to do a hard refresh on the page. This shouldn’t happen if we make the outer frame simple enough and don’t introduce any major bugs (that said in practice it will happen every once in a while). The vast majority of the code and attack surface should be inside of the inner app, which will be able to be updated more frequently.
This could be massive as if it works, it could allow us to do a web app in a way that approaches the security of a native desktop app.
Would love to start a discussion here and hear about everyone’s thoughts and about other options we should consider.