Zcash Project Hardening via the Permaweb & ArNS

I’ve been asked (not paid) to post a public explainer on how to leverage the permaweb in order to bolster the security of Zcash projects. (These techniques could apply to any project but Zcash protects your anonymity as you deploy the defenses suggested herein.) Any relevant comments, questions, or criticism are welcome.

Ground rules: DYOR, use onion routing and onion websites whenever possible, and assume that DNS is sometimes lying to you, even about this forum.

The whole point here is to harden ourselves against Web2 vulnerabilities, first and foremost Github, which is absurdly one of humanity’s most centralized dependencies. Even multiple data center redundancy isn’t robust enough in the era of agentic attacks.

Everyone here depends on the integrity of binary executables (such as APK packages for Android apps). Nobody wants to trust an app store, let alone one tied to one’s banking details. It’s therefore preferable to sideload an APK with a robustly verifiable hash, at least for those who know what they’re doing.

Some of us also depend on source code. These days, it’s not hard to imagine an attack in which an agent swarm steals, say, your Gitlab credentials and uses them to publish a malware app on your repo. You might eventually recover control but how far did the fire spread in between times? How many downstream compromises happened as a result, which might not manifest for years? While you can only do so much to ensure that your own upstream package dependencies are clean, you can, at least, ensure that your downstream consumers install the intended executable or read the source code that was actually used to compile it. Reproducible builds and signed executables (ideally, multisig) are a good starting point but they don’t protect you from Web2 mutability. We just had a major docs hack this week, so this advice applies to that as well.

Back to the permaweb (Arweave blockchain). As the name suggests, it’s just like the normal web but readonly. You pay some AR to upload a file and, usually within half an hour, it settles on chain. Oh no! Someone stole your AR wallet keys? Nevermind. They can’t alter files that have already finalized. Files larger than 12MiB (12,582,912) are not guaranteed to be served but we all know how to deal with that.

Now you can go back to yourdomain[.]com and point everyone to an immutable copy of your code, docs, and executables (ideally, your entire website) on Arweave. The links will look like this:

https[:]//arweave[.]net/abc123…

where that junk at the end is a TxID that you can view in an Arweave explorer, along with its SHA256. Any given explorer can lie to you but there are plenty of them.

Problem solved! Now you’re immune to a whole zoo of attack species. But wait: yourdomain[.]com lives on Web2, as well. So maybe a hacker can break into it and post their own fake Arweave link to your “new improved app” and distribute malware.

Enter Arweave Name Service (ArNS). It allows you to register yourdomain, but instead of yourdomain[.]com, you get yourdomain[.]ar[.]io as well as yourdomain followed by hundreds of other suffixes. Those suffixes are known as “gateways” and each of them should point to the same Arweave object. A rogue gateway could redirect visitors to a malware site, just as someone could theoretically redirect github[.]com, but users who are made aware of this hazard (by your installation docs) will know that they should form a consensus across a multitude of active gateways browsed from random IPs using random DNS providers. The gateway list is public at:

https[:]//gateways[.]ar[.]io/#/gateways

Just like any conventional website, the gateway website itself is susceptible to redirection, so it’s useful to record some suffixes for future reference and list them in your docs. But hacking the gateway website will not redirect yourdomain[.]ar[.]io. That can only be done by a Solana wallet.

It works like this: every time you want to update your website, you just make a new home page, upload it to Arweave, and point to it from yourdomain via an ArNS transaction on Solana. (You must have control of the wallet which owns yourdomain.) That control can be spread across a quorum using MPC wallet services which already exist on Solana. However, my sense from the ARIO team (who maintain ArNS, although someone else could also do it) is that they’re enthused about adding native multisig support in the future. At least you can choose which wallet to use and you’re not trapped in the Web2 walled garden.

ARIO allows you to rent or buy an ArNS domain using their Solana token of the same name (but watch for fakes). Their registration site is:

https[:]//console[.]ar[.]io/arns

but in theory you could do so directly via a smart contract interaction. Anyway, once a domain is registered, it works fine. However, the registration process itself is still a bit buggy and requires some simple workarounds…

https[:]//github[.]com/ar-io/ar-io-sdk/issues/775
https[:]//github[.]com/ar-io/ar-io-sdk/issues/774

If that scares you off then at least you know about all this and you can wait until they fix the issues, I would guess later this month. Or just lease for a year in order to minimize risk, as you can always top up later. Just don’t forget because anyone else can legitimately seize your domain the moment it expires.

For its part, AR is available from various CEX and crosschain services. Wander and arweave.app work in Tor but just use them for whatever small amounts you need for uploading.

Full disclosure: you can see my wallet history and all its ArNS domains (no affiliation apart from my own name, just speculative investments) at:

6ZPCznNwW2fqhB39cypYQsN3w9LpX3MbjqHSYqqVQvUY

on Solscan. All of them were acquired through the (buggy) registration flow. You can DM me if you want to ask about any of that but this thread is focussed on ArNS and the permaweb. (Tech support scams will be routed to AI.) For the record, I’ve also submitted bug reports and feature requests against the zodl-inc repo on Github, including about ArNS security hardening and AR swap support, but they have not replied. I have no affiliation with Zodl or ARIO but I’m a fan of both, frustrations notwithstanding.

1 Like

Summary

Normal websites, GitHub, and app stores can be hacked or quietly changed. Someone can swap real software for malware.

This post suggests a stronger setup:

  1. Put the real files on Arweave (the “permaweb”).
    You pay once in AR and upload the code, docs, or binary. After it settles (~30 minutes), nobody can change that specific copy — not even if they steal the wallet keys. The data is addressed by a permanent TxID.

  2. Give it a readable name with ArNS.
    Instead of a long random ID, you get something like yourproject.ar.io (and the same name on hundreds of other gateways). The name points to the Arweave file. Many independent gateways all resolve the same name, so you can check several of them and take a consensus.

  3. Updating means uploading a brand-new immutable version to Arweave, then changing the ArNS pointer (controlled by a Solana wallet / ANT). The old version stays forever and is still reachable by its original TxID.

  4. Zcash is recommended for the funding/upload steps so the publisher is harder to track.


Bottom line

It does not make the name itself immutable (the pointer can still be updated by whoever controls the Solana wallet), and users still need to verify gateways, but it removes the ability to silently rewrite published files and binaries after the fact. That is a real improvement over ordinary web hosting or GitHub for distribution integrity.


The 12 MiB note and registration quirks the author mentions are also real practical details. Overall the technical claims hold up.

The 12 MiB limit

They meant the old practical limit on inline Arweave transaction data.

In early Arweave (especially format/v1 and simple v2 posts), the data field of a transaction was limited to roughly 12 MiB (exactly 12,582,912 bytes). Nodes would accept that much inline; anything larger had to be uploaded differently. The protocol itself supports far larger sizes via chunking, and modern bundling removed the practical problem years ago.

How to deal with it:

  • Bundling (ANS-104) — the normal way today. Tools like Turbo (ar.io / ArDrive), older Bundlr, or self-hosted bundlers package data into signed data items and settle them in larger base-layer transactions. You just upload; the bundler handles splitting and packaging. The resulting data is still permanent and addressable by its own ID.
  • Chunked upload — for a raw transaction you submit the header (with data_root and data_size) then POST the data in chunks via /chunk. Gateways reconstruct and serve it.
  • Manifests — for multi-file things (websites, source trees) you upload a directory via a bundler; it creates a manifest TxID that acts like a folder.

In practice, for the use case in that post (binaries, source, docs), you just use Turbo or the Arweave JS SDK with a bundler. The 12 MiB note is a historical caveat, not a current hard limit. Once settled, the data is immutable and served by gateways the same way regardless of how it was uploaded.

1 Like

Thank you for the excellent summary! Hopefully that’s more readable for everyone. I would just emphasize:

No gateway gets a free pass for trust, not even ar[.]io which is controlled by ARIO itself. So users need to make a habit of sampling several of them, new and old, common and obscure. I just use ar[.]io as an example because it’s the original and has exemplary uptime history.

Yes, it’s true that Turbo services can serve beyond 12MiB. However:

  • On the upload side, ArDrive is slow and unwieldy for more than ~10 files. It claims to support the creation of manifests, which supposedly humanize Arweave URLs, but your Arweave object will usually have a file extension (such as “.ZIP”) automatically appended by the browser upon download, so manifests may be unnecessary.

  • arweave[.]app is much faster and cleaner for uploads (although I haven’t tested size limits) and it doubles as a web wallet which might be trustworthy.

  • Some gateways throw up a paywall when you try to download a “big” file. Then they fail for some other reason even if you’re willing to pay. And other gateways just fall flat. However, I haven’t put much effort into determining what “big” means beyond 12MiB. Your typical ~100MB Zcash app may or may not slide under the radar.

  • One option is to sidestep the issue by uploading “big” files to a mutable data store such as IPFS, then providing a SHA256 along with a link on your immutable website. Documentation and source code can and should reside on the permaweb, as they hardly ever involve files exceeding 12MiB.

1 Like