Making Browser Crypto Safe for the Modern Web

For several years, the consensus in the development community has been that browser cryptography, via JavaScript, is a bad idea. There are many different reasons for this opinion, some of which are more dated than others. With our TozStore product, we aimed at making browser-based cryptography safe for our users.

Old-School Challenges

There are at least three fundamental challenges facing browser cryptography:

Secure Communication

Until recently, enforcing TLS encryption on webpages was expensive and cumbersome to configure. You needed a pricey certificate from a third party, had to reconfigure your web server to support the traffic, and might miss out on some traffic unless you had a dedicated IP address for your machine. Without this kind of security, potential attackers could both eavesdrop on and modify any data flowing over the wire. This includes the actual scripts being used to perform cryptographic operations within the browser!

Script Interference and XSS

Browser cryptography is, at its core, an exercise in trust. Users need to trust that site administrators are building a smooth, secure UX. Site administrators need to trust that outside vendors are delivering clean, bug-free scripts. Everyone is trusting that the scripts running in the browser are working as advertised; not stealing data, not corrupting information, not leaking any secrets. As sites can load scripts from any location, and these scripts can modify the behavior of one another, it can be difficult to trust that the environment is secure, no scripts are interfering with the cryptography, and that third party sites aren’t injecting malicious instructions.

Actual Randomness

Older browser versions only supported the vanilla Math.random() function for generating random numbers in JavaScript. This function, however, is not cryptographically secure. In many cases, it can be seeded deterministically and the values it produces can be predicted ahead of time. If Math.random(), is depended upon in a cryptographic environment, breaking that cryptography becomes trivial.

New-School Solutions: Tozny’s Admin Console

Tozny’s Admin Console, which is the portal where customers both sign up for and manage their TozStore account, addresses all of these concerns and more. The Console is a single-page JavaScript application, served from Amazon S3 via CloudFront and running entirely within the user’s browser. Thanks to new Amazon tools like Lambda@Edge, the site implements strong security headers as well.

Secure Communication

The entire Console app, both pages and assets, is served only over an encrypted HTTPS connection. In addition, the server automatically redirects any first-time requests to the unencrypted API back to the encrypted location. The server also enforces HTTP Strict Transport Security (HSTS) headers to force browsers to only interact with the API over an encrypted connection. This prevents third parties from eavesdropping on any communication and ensures that the scripts sent to the browser are unmodified in transit from Tozny’s servers.

Script Interference and XSS

Modern browsers implement different tools to prevent scripts from containing malicious injections. One of these tools is a Content Security Policy (CSP). A CSP allows a website to identify and explicitly whitelist the domains and types of assets that are allowed to load on the page. If a script from an untrusted source is injected into the page, the browser will block that script’s execution. The Console explicitly identifies the only locations allowed to load scripts – and blocks other unsafe tools like JavaScript’s eval() function. The only scripts that can execute in the console are those provided by Tozny directly (or by Stripe specifically for billing purposes).

Actual Randomness

The Console uses browser cryptography both during authentication and to protect stored values the server is not meant to see. In both instances, the Console leverages libsodium.js, which in turn uses the cryptographically secure random number generator built into the modern WebCrypto API. Leveraging these strong, publicly visible tools makes it easier for outside parties to vet and verify the work performed under the hood.

TozStore Script Security

The front-end TozStore scripts implement browser cryptography as well and, like the Console itself, leverage strong security to protect from abuse. Firstly, these scripts are only ever delivered to client sites over HTTPS, providing a secure line of communication from your users’ browsers directly to Tozny’s content delivery network.

Secondly, Tozny publishes the SHA hash of these scripts’ contents publicly, enabling your site to leverage Subresource Integrity (SRI). Subresource Integrity allows the site to specify a valid hash for any scripts being used. After the browser downloads the scripts, it will independently verify the hash before allowing execution. This prevents any potential manipulation of the scripts in transit, making it easier for end users to trust the integrity of the operations being performed in the browser.

Finally, Tozny strongly encourages anyone integrating with TozStore to follow the best practices outlined by tools like Mozilla’s Observatory. Observatory will proactively scan your site to ensure it consistently:

  • Implements a strong Content Security Policy and whitelists the safe sources allowed on the site
  • Blocks Cross-origin Resource Sharing to prevent remote interaction with the site
  • Implements HTTPS for encryption
  • Forces HSTS to prevent security downgrade attacks
  • Protects against iFrame embeds and sets XSS Protection headers

Scoring an A+ with Observatory doesn’t necessarily mean that your site is 100% secure. It does mean you’re following best practices and making solid steps towards a stable, secure website and can more safely use tools like browser cryptography on modern browsers. Tozny’s Admin Console scores an A+, and we are committed to providing the best tools possible for you to safely integrate browser cryptography tools like TozStore with your own site.

Note: If you think you’ve found a flaw with any part of this approach, please contact us and let us know.

Series NavigationEncrypting strings in Android: Let’s make better mistakes >>