How to verify browser-local encryption never sent plaintext

Whether “browser-local encryption” is worth trusting is not a slogan—it is which requests this action sent. Search Network with a canary that appears only in this experiment: request lines, bodies, and analytics should not contain plaintext, a passphrase, or the key after #. AES-256-GCM should finish in local Web Crypto before any ciphertext leaves.

Start with the conclusion: what you can verify on the spot is whether this HTTP request sent plaintext, a passphrase, or a fragment key as business data. It does not prove an extension did not read the clipboard, and it does not prove the next version will behave the same. The steps below are repeatable—not a new set of adjectives.

Answer the search intent in one sentence

Browser-local encryption means encrypt and decrypt happen in the tab you are looking at: the script calls the browser’s Web Crypto API, finishes AES-GCM-class algorithms on this device, and plaintext and keys do not leave the browser as HTTP bodies by default. The check is not a marketing sentence—open DevTools Network, search a canary, then retest offline if needed.

This article is for developers, ops, and anyone who wants to look before handing a file or passphrase to an “online tool.” It does not replace the File Encryption Box how-to, and it does not repeat the homepage product definition. What you should take away is a check you can reuse on any site.

Slogans cannot prove themselves; traffic can be observed

Many pages print local compute, zero upload, and end-to-end. Those words can sit on a tool that truly finishes on this device, or on an upload page that POSTs the original text so a server can encrypt it. The sentence itself has no checksum.

What you can see on the spot is the method, URL, query string, and body this tab sent. Chrome’s Network panel lists them. If the file name you just picked, the passphrase you just typed, or a sample only you know appears in those places, “local encryption” did not hold for this action.

The reverse is also narrow: no plaintext in the panel only means the requests you observed did not carry those fields. It does not mean memory held no plaintext, and it does not mean a browser extension did not read the input. Turning marketing into one repeatable observation is already useful: you can tell a colleague “I searched the canary; the request line and body are clean,” instead of forwarding a homepage sentence.

Do not experiment with a real key, ID number, or an unredacted spreadsheet. Prepare a disposable small file, and use a one-time long passphrase. You are checking traffic—not exposing privacy again.

Which layer “local” actually means

“Browser-local” is not “this domain looks safe.” It means cryptographic work happens in the current document’s script environment. For AES-256-GCM, the usual correct path is crypto.subtle.encrypt: key derivation, encryption, and the auth tag all go through the browser’s own API. MDN states that SubtleCrypto.encrypt is available only in a secure context—HTTPS in production. On a plain HTTP page, crypto.subtle is often undefined.

AES-GCM is chosen for more than the name. It is authenticated encryption with integrity: if the ciphertext is altered or the wrong key is used, decrypt fails instead of emitting “garbage that looks like plaintext.” The IV is commonly 12 bytes (96 bits), matching NIST SP 800-38D’s recommendation for GCM. Each encryption should use a fresh random IV so the same plaintext yields different ciphertext.

A file flow can be written as concrete actions: you pick a local file, the script reads it in chunks, encrypts each chunk, then triggers a browser download of the ciphertext. The downloaded .lock or .enc is a file this device produced—not a server receipt. A 5 GB single-file cap describes streaming in the browser; it does not mean a remote host received 5 GB of plaintext.

Also separate “business upload” from “requests the page makes anyway.” A ready-to-use toolkit still loads CSS, scripts, and fonts, and it may send visit analytics with no body. Those requests are not proof that “the file was uploaded.” But if an analytics query or body contains the passphrase you just typed, a password you audited, or text before redaction, that is a different matter.

FastPwd writes this boundary as a sentence you can check: plaintext and keys for password generation, Password Audit, privacy cleaning, and file encrypt/decrypt stay in the browser by default; Burn-Link lets only ciphertext leave, and the decryption key sits in the URL # fragment. File Encryption Box chunks at 1 MB and derives an AES-256 key from the passphrase with PBKDF2 (100000 iterations, SHA-256), then writes .lock / .enc. Every tool is ready to use—no account and no vault. A promise is still only a promise. Below, Network turns it into a checklist.

Run a canary check in Network

First prepare a marker that will not appear in real work. A file name can be canary-fp-20260825.bin, the passphrase a random long sentence, and the body a line that exists only in this experiment. The canary is for search: paste it into the Network filter; a hit is a fail.

Open DevTools, switch to Network, check Preserve log, and start the filter on All—do not leave only XHR. A canceled or 4xx request may already have carried plaintext. Then complete one full action: pick a file, enter a passphrase, click encrypt or generate. Do not close the panel when you finish.

  1. Paste the canary into the filter. A red hit means stop and read that request—do not fall back to “it feels local.”
  2. If there is no hit, open Fetch / XHR one by one and check the request line, query string, and body. CSS, fonts, and scripts can be ignored.
  3. Filter analytics paths separately and open the query and body. Page titles and paths may appear; the passphrase you just typed, a password you audited, text before redaction, and file contents should not.

Read the request line

Read the path and the query after the question mark, character by character. Locator fields such as id may appear; a file name, passphrase, password you audited, or the key after # should not. Compare the full address-bar string with the request line: if the part after # entered the request line, the implementation treated a fragment as a query, or a script read it and wrote it into a request.

Read the request body

The POST / PUT payload is the second place. If file encryption claims to finish locally, the body should not hold the original file bytes or the passphrase. Burn-Link may include a ciphertext field—that is expected outbound data; confirm it does not look like the plaintext you just typed. If a Password Audit page POSTs the password, whether the purpose is written as “leak lookup” or “score strength,” it has already left this device.

Inspect analytics separately

Visit analytics is often skipped. A clean main API with a report that carries the full input still means this action did not keep “plaintext in the browser.” When you filter analytics paths, do not assume “the analytics script is harmless”—it is another outbound request, checked the same way as a business API. FastPwd analytics uses the site’s own tracker and does not send from localhost by default; even so, search the canary and confirm the report has no passphrase or file contents.

Check Preserve log. If the page navigates or reloads after encryption and the box is unchecked, the first request that carried plaintext may already be gone—and you get a false “the panel is empty.”

Retest offline: static assets are not a business upload

The second check is cheap. Let the page finish loading, then turn on Offline in Network—or cut the system network—and encrypt that disposable small file. If the .lock download still completes, this encrypt/decrypt did not need a live API. That is a strong signal for “browser-local encryption,” but not the only one.

False failures are common too: a font or analytics script turning red under Offline is not an encryption failure. Watch whether a new business POST appears after you click encrypt, and whether the result file is already in your downloads. False passes exist as well: a script can queue plaintext and send it after you reconnect. So pass the offline test, then still run the canary search while online.

The question mark enters HTTP; the hash does not, by default

A URL has two parts people often mix up. The query after the question mark enters the HTTP request line; servers, reverse proxies, and access logs can all see it. The fragment after # stays in the browser by default, for the current page’s script to read. The HTTP request target does not include the fragment—that is RFC 9110 on request targets, and why URL.hash exists only on the browser side.

So if a one-time ciphertext link puts the key in #, when the recipient opens s.html?id={id}#{key} the server is designed to see only id, not the key. That is not an extra crypto protocol—it is the browser’s default fragment behavior. It has limits: paste the full address into a ticket, a group chat, or a preview card that drops the hash, and the key moves from “does not enter HTTP” to “appears on someone else’s screen and logs.”

The check is equally concrete: create a harmless test note in Burn-Link and see whether the create request body is ciphertext only; on the read page, see whether the document request and later APIs contain only id in the URL. The part after # in the address bar should not appear in those requests. The read page is public for the recipient—no login.

Where to look Enters HTTP? What counts as a pass
Page slogan Not involved Not proof—use only as contrast
Request line / query Yes No canary, no passphrase, no fragment key
POST body Yes No plaintext; Burn-Link may send ciphertext only
URL # fragment No, by default In the address bar, not on the request line
Visit analytics Depends on the implementation No input-box plaintext
Encrypt after Offline No new business request Ciphertext still downloads; search the canary again online

What you can prove—and what you cannot

The conclusion this check supports is narrow. Writing that down makes it more useful.

It can support: in this browser, this version, and this action, plaintext, the passphrase, and the fragment key did not leave the tab as observed HTTP business data or analytics plaintext.

It cannot support: no other tab or extension is reading the clipboard; the downloads folder on disk is safe; the recipient will not screenshot the ciphertext; Password Audit covered a full-web breach corpus. If the check only does local entropy plus a public weak-password Top list, it can answer “does this look like a common weak password,” not “it never appeared in a breach.” That is not a full-web HIBP lookup.

Do not read it as a penetration test either. You did not inspect WebSockets, Service Worker caches, or reverse a minified script. The goal is to explain to a colleague: I opened Network, searched a canary, and the request line and body are clean. That is closer to an engineering discussion than forwarding “the site says nothing is uploaded.”

FAQ

If it still encrypts offline, does that prove nothing was uploaded?

It only proves this encrypt/decrypt did not need a live API. Scripts already cached on the page can still send later when you reconnect. So pass the offline test, then search Network again with the same canary while online. Both steps must pass before the conclusion holds.

If the Network panel is empty, was this action safe?

No. A filter left on Img only, Preserve log unchecked, or a request cleared on navigation can all produce a false blank. Switch the filter to All, search the canary, and open analytics reports separately. An empty panel is a failed observation, not a security proof.

If Burn-Link stores ciphertext on the server, is that still browser-local encryption?

It counts as “plaintext finished locally, then ciphertext leaves.” The server should see only ciphertext and a lookup id; the decryption key sits after the # in the link and does not enter HTTP by default. Create and read need no account. Check that the body is not plaintext, and that the request line does not contain the key after #.

Does Password Audit send the password to a full-web breach database?

FastPwd’s Password Audit scores strength on this device and checks a built-in public weak-password list. The password is not uploaded. It can catch common weak passwords, but it cannot prove “never seen on the web,” and it is not a Have I Been Pwned-style lookup. Search Network with the password as a canary to verify this claim.

Use the same steps on a ready-to-use tool

If you want a page with a written compute boundary to practice on, start with FastPwd’s File Encryption Box. Open and use it—no signup. Pick a small file with no real privacy, use a canary as the passphrase, encrypt, and download a .lock. Watch Network at the same time: you should see static assets and possibly visit analytics, not the original file or passphrase as business fields. The algorithm is AES-256-GCM in Web Crypto; a single file is at most 5 GB.

Burn-Link is a good second drill: create a harmless test note and confirm outbound data is ciphertext; the read page is public for the recipient, and the link shape is s.html?id={id}#{key}. Privacy cleaner is good for “does the original text enter analytics”—links and text to redact stay in the browser as the product describes; you still decide whether the cleaned result is enough.

These drills are not meant to prove any one site is “absolutely safe.” They are meant to make the same check familiar. On any page that claims local encryption, the steps stay the same: canary, Preserve log, request line, body, analytics—and Offline if needed.

Remember three things the next time you check. First, watch traffic, not slogans. Second, outbound ciphertext is acceptable; keys and plaintext are not. Third, after you change browser, version, or feature, run the canary search again. Only a repeatable observation is worth putting in your own security notes.