Security
A precise account of what we protect and what we cannot
Security claims are only useful when they are specific. This page lists the threat model, every network request the site makes, everything stored on your device and the response headers we send.
Threat model
What is in scope
The design goal is simple: your document must never leave your device because of us. That protects against a specific set of risks and leaves others to you.
| Scenario | Status | Notes |
|---|---|---|
| Your document being uploaded to our servers | Protected | There is no upload endpoint. Processing runs in a Web Worker on your device. |
| A data breach at Unformation exposing your files | Protected | We hold no files, so there is nothing to breach. |
| Someone on your network reading your document in transit | Protected | It is never in transit. The site itself is served over HTTPS with HSTS. |
| The AI provider learning names, IDs or account numbers you paste later | Protected | That is what the tool is for, provided you review the list and the mapping table stays with you. |
| Malware or a malicious browser extension on your device | Out of scope | Anything that can read your screen or memory can read the document before and after anonymization. |
| Screenshots, printouts and copies you make | Out of scope | The anonymized file is yours; where you send it is your decision. |
| The AI service you paste the result into | Out of scope | We only remove what you asked us to remove. Read the provider's data policy for what remains. |
| Missed detections | Out of scope | No detector is perfect. Always review the list before downloading; add missed words to your dictionary. |
| Someone who obtains your mapping table | Out of scope | The mapping table reverses the anonymization by design. Store it like the original document. |
Data flow
Where your document goes
- 1
You select a file. The browser reads it into memory on your device.
- 2
The bytes are passed to a Web Worker running on the same page.
- 3
The worker unpacks the file, extracts text and runs detection (patterns, dictionary, optional model).
- 4
You review the list; the worker writes replacements back into the same file structure.
- 5
The result is offered as a download. Nothing is sent, logged or stored by us.
- 6
When you close the tab, the file and the results are gone. Only your dictionary and one preference stay in localStorage.
Third-party requests
Every external request, listed
This is the complete list. Anything not on it does not happen. You can confirm it in the Network tab.
| Service | When | What they can see |
|---|---|---|
| Fonts | Never | Fonts are self-hosted and served from unformation.app. No request goes to Google Fonts or any font CDN. |
| Vercel Web Analytics | On page view | Cookieless, aggregated page-view counting: page URL, referrer, coarse device and country. It never sees your documents. See the privacy policy for details. |
| Hugging Face Hub CDN | Only when you enable smart detection, once | The model files are downloaded from huggingface.co / hf.co. Their servers see your IP address and the request, as with any download. The files are then cached in your browser; later runs make no request. |
| Anything else | Never | No error trackers, no chat widgets, no ad or social scripts, no embedded third-party content. |
On your device
What is stored locally
| Where | What | Why |
|---|---|---|
| localStorage | Your dictionary (unf.dictionary.v1) | So the words you always want replaced survive a page reload. Delete entries in the tool or clear site data in the browser. |
| localStorage | First-visit notice flag (unf.notice.v1) | So the one-time note about no cookies is not shown again. |
| Cache Storage | App shell (scripts, styles, pages) via the service worker | So the tool loads and works offline after the first visit. |
| Cache Storage | Model files, only if you enabled smart detection | So the model is downloaded once and then works offline. |
| Cookies | None | The site sets no cookies, first- or third-party. |
Transport and headers
Security headers we send
Served by Vercel over HTTPS. These headers are set for every response; you can inspect them in the Network tab. The values below are copied from the configuration, not paraphrased.
| Header | Value | Effect |
|---|---|---|
| Content-Security-Policy: default-src | default-src 'self' | The baseline: every resource type not listed separately may only come from unformation.app. |
| Content-Security-Policy: script-src | script-src 'self' 'wasm-unsafe-eval' 'unsafe-inline' https://va.vercel-scripts.com | Scripts come from our origin plus the cookieless Vercel Analytics script; there is no other third-party script. 'wasm-unsafe-eval' lets the browser compile the ONNX WebAssembly runtime for optional smart detection. 'unsafe-inline' is present because Next.js statically rendered pages ship small inline bootstrap scripts (hydration data, no user content). We list this honestly: it weakens CSP against injected scripts, but nothing on the page renders untrusted HTML and no eval is allowed in production. |
| Content-Security-Policy: connect-src | connect-src 'self' https://huggingface.co https://*.hf.co https://cdn-lfs.huggingface.co https://cdn-lfs-us-1.huggingface.co https://va.vercel-scripts.com https://vitals.vercel-insights.com | The page may open connections only to our origin, the Hugging Face Hub (contacted once, and only when you enable smart detection and download a model) and the Vercel Analytics endpoints. Your documents are never part of any of these requests. |
| Content-Security-Policy: workers, frames, style, img, font | worker-src 'self' blob:; child-src 'self'; frame-ancestors 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self' | The anonymization Web Worker is loaded from our origin (blob: allows the runtime to spawn helper threads for the model). No frames, no plugins, no external fonts or images; the site cannot be embedded elsewhere and no form can post to another host. |
| Strict-Transport-Security | max-age=63072000; includeSubDomains; preload | Browsers only connect over HTTPS for two years, and the domain is submitted for preload lists. |
| X-Frame-Options | DENY | The site cannot be embedded in another page (clickjacking protection); CSP frame-ancestors says the same. |
| Referrer-Policy | strict-origin-when-cross-origin | Other sites you navigate to receive at most our origin, never a full URL. |
| X-Content-Type-Options | nosniff | Browsers respect the declared content type instead of guessing. |
| Permissions-Policy | camera=(), microphone=(), geolocation=(), interest-cohort=() | The page cannot request camera, microphone or location, and it opts out of interest-based cohort tracking. |
Responsible disclosure
Found something? Tell us
If you believe you have found a way for a document or personal data to leave the device, or any other security issue, please email the address below. Include steps to reproduce; you will get a reply, and a fix will be published in the changelog. Please do not test against other users' data, there is none on our side, but be considerate anyway.
yurtgoktug@gmail.com
Machine-readable contact: /.well-known/security.txt