Safe web deployment of the Blockstack app (authenticator / ID wallet)

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.

6 Likes

I love this idea, but would this mean that desktop installs would be done away with entirely if this were successful? I ask because there’s a vision I continue to pitch for Graphite/Blockstack that makes it nearly censor-proof:

Normally a user would download the Blockstack Browser from blockstack.org/install. Today, it’s possible for a government to block access to all of blockstack.org for its residents. But because of the nature of the browser today, someone with the browser install code could load that up on thumb drives and distribute it to people in that community. Those people would be back up and running with the Blockstack Browser. But what about the apps?

This is a big reason why Graphite is open source. In that type of environment, I want people to be able to also load Graphite up on thumb drives and run it locally (assuming in some weird world Graphite and Blockstack are both blocked). Because the browser is run locally and Graphite is run locally, these people who would otherwise be censored can still share documents, data, files, and communication.

I know that’s a bit of an edge case and your solution, Ryan, would solve a huge roadblock for normal user adoption, but I just want to plant this seed. Beyond security, the native browser serves a big purpose in censorship resistance.

Please let me know if I am misstating anything in my assumptions or misunderstanding anything.

Not necessarily.

I’d note that with the code open source, anyone could host the same app on any domain.

Additionally, a browser extension could be offered as an alternative.

1 Like

Awesome! A browser extension makes a ton of sense, but asking someone to host the code themselves seems less likely. Either way, I’m glad there will be options. Thanks!

To clarify, based on a question someone posted in the slack, the index.html would have to be hashed and all of the internal includes would be required to have SHA-256 integrity strings as well. Which means you can view the hash of the index.html file as a hash of a file with hashes in it AKA a pseudo merkle tree.

Thought about similar things since some time now. I think the idea of having a “immutable” code verifier and a frequently updated app is the way to go. The idea with using browser caches for this is interesting :wink:

I also could imagine an addon that verifies websites / web apps against a key. (Given that the browser prompts the user if there’s an update, maybe also disabling updates?)

And finally, I stumbled across https://github.com/airbornio/signed-web-apps last week. Tries to solve the same problem, but not finished yet. It uses service workers to place a code verifier.

Thanks for the clarification, this makes a lot more sense now. I was thinking only the index.html file would be hashed.

Was there a method you had in mind for setting up nodes to report the latest hash of the application? Like, what would the process be to update the app hash?

1 Like

With Progressive Web Apps you have a similar issue that you want to update the app only if you are online. So, there is already hashing of the content and update mechanism that comes with service workers. Maybe have a look at precaching of https://developers.google.com/web/tools/workbox/

1 Like

Also this: https://github.com/WICG/webpackage