The only perceivable reason to want to secure a SPA without a backend is to avoid costs as much as possible. Securing without a backend is an almost impossible task. But still, you can secure some parts using browser encryption before building and deploying.

And you can avoid huge costs since you can serve millions of static high-quality requests virtually free.

But then again, what good is that? After all, without an API, or a database, you practically serve something akin to a book, and you can't call that an application. And if you do have a database and API then the costs of having an auth middleware before serving the frontend or even full-fledged SSR is minimal compared to the costs of the infrastructure for what is executing your business logic.

There is an exception. That is when it is not your API/database, and you just run a client that consumes execution from someplace where costs are covered by somebody else.

In that case, you have 4 avenues:

1 Use browser encryption. Encrypt everything with a single symmetric password that users can use to decrypt the SPA - has 0 cost

2 Build a light backend on top of browser encryption with a user system that will let you share the encryption password but not directly and make it seem like you have a multi-user system ( has some minor to no cost of running some edge worker that will act as a backend )

3 Don't use browser encryption. Just use a worker as a fake auth system and do auth in the client, which can be bypassed if users inject some client code or modify client execution. In essence, this has the same cost as 2. It has the disadvantage that can be easily bypassed, but maybe that is not vital, and you are okay with that. As long as it requires a bit of effort, and most non-technical people won't bother. It has the advantage of being faster, and cheaper, not using browser encryption, and avoiding potential issues.

4 Do a proper auth middleware and serve the page based on auth middleware. Generally, this is the best method, but it will cost the most. So depending on your goals, you might not want that. Especially if what you have is mostly a hobby project

You may think using browser encryption is intriguing but it has some pitfalls. First of all, for browser encryption to work you need a way of replacing the current document with a new one that was decrypted in memory.

Although all browsers support the replacement of the document, it is not perfect and is not the same as if you serve the first document request. I think most people assume this is by design to prevent security issues, but I am not so sure since we already have a way to replace the document that is almost perfect in the sense of reloading the document, not necessarily performance-wise.

From what I experimented using document.write has the best results in terms of reloading the page, even if it has advanced JS, like a framework, or uses many libraries. But is not perfect because it will create some flashing effects that can't be fixed also it will break integration with Chrome extensions that are meant to interact with the page, like for example crypto wallets.

As events listeners and window global variables might be detached by rewriting the page with document.write.

This means browser encryption will never work perfectly without browsers adding a new API, that will probably not happen, since even if there are new features added to Web APIs like every few months now, many innovations have been dragged for years due to potential security/privacy consideration, which most times are overblown, at least on the Web APIs, I think extension APIs are another discussion.

So, in conclusion, browser encryption will work mostly as long as your website does not interact with a browser extension, so if you want to try out the first avenue you can check this package https://github.com/Greenheart/pagecrypt for the second one you can check this: https://github.com/andrei0x309/pagecrypt-light-backend which is built from the first one If the page is not yet public probably I'll make it so I can't know for sure if the second link will work.


Tags

Related Articles

Semi-open Github Repos
Semi-open Github Repos

If you ever had a repo and didn't want to set it completely open, then you didn't have many choices. For example, Gitlab at least lets you have a public repo with private code, but this isn't a thing for Github.So I thought of a simple system where you have a ...

Read more
PartyTown On SvelteKit
PartyTown On SvelteKit

To start, I'll say what party town is, in a nutshell: it's a tool to get some of your execution out of the main thread and into a worker. It's doing that by communicating between the worker and the main thread, which will primarily execute DOM updates.More in-...

Read more
Github Contribution Table
Scrap / GET Contribution Table from GitHub

So when it comes to some products like Twitter & GitHub, there are ways to either access non-public APIs or minimum, to scrap info that we can't take easily with the official API.For Twitter, I think it is more important because you can access a lot of dat...

Read more