Your data stays in your browser
There is nowhere for it to go. That is a property of how this site is built rather than a policy I am asking you to trust.
What this site is
CardTools is a static site. Every page is pre-rendered HTML with JavaScript attached; every parser, decoder and lookup table is compiled into that JavaScript and runs on your machine. There is no server-side code, no database, and no API. The only things a page ever fetches are its own HTML, CSS, JavaScript and fonts, all from this domain. Nothing you type is ever part of a request.
So anything you type or paste, whether that is a card number, a chip trace or a message dump, is processed on your machine and discarded when you close the tab. It is never uploaded and never stored.
How to verify it
Don't take my word for it. Open your browser's developer tools, switch to the Network tab, and use any tool on this site. Type into it, paste into it, press its buttons: no request carrying your input appears.
Two things you may see, so that they do not look like I am hiding them. On the reference
tables, a file under /_astro/ arrives a moment after the page does. That is the
page's own JavaScript, fetched when the browser goes idle rather than up front, because
those tables are readable before their search box works. It is the same origin, it carries
nothing from you, and it has finished before you have typed anything.
The other is a font. The typefaces are split by alphabet and each piece is fetched only when
the page first needs it, so the first time a page shows monospaced text, or you type a
character from an alphabet not yet on screen, such as Cyrillic or Greek, a
.woff2 file under /_astro/ is requested. That one can follow your
typing, but its address is fixed when the site is built and it carries nothing from you.
For a stronger check, load a tool page, then disconnect from the network entirely. Everything keeps working. A tool that needed to send your data somewhere could not.
You can also read the source. Every parser is a plain TypeScript function with no network calls anywhere in it.
The strongest check is the Content Security Policy this site is served with. You can see it in the response headers in the Network tab. Two directives are doing the work.
connect-src 'none' tells your browser to refuse every connection a script can
open: fetch, XMLHttpRequest, WebSockets, EventSource
and sendBeacon, including back to this site's own domain. That is the whole
category an analytics beacon or an exfiltration attempt would use.
default-src 'self', with img-src 'self' data:,
font-src 'self' and form-action 'none' beside it, closes most of the
ways around that. No image, script, stylesheet, font or form submission may go to any other host,
so the usual trick of smuggling data out in an image URL fails too.
script-src does not allow 'unsafe-inline'. It lists the hash of each
inline script the site really contains (the one that applies your light or dark theme before
the page paints, and the small bootstrap that starts each tool) and nothing else, so a script
that somehow ended up in a page would not run. You can see the hashes in the header, and they
are generated from the built pages at deploy time rather than typed in.
What that buys you is that a bug, or a dependency I trusted turning out to be compromised, could not quietly post what you typed to another server in the background. To be precise about what remains, because a CSP does not cover everything: a same-origin subresource request is still permitted, so code running on this page could in principle put data in a path on this domain and have it appear in the host's request log. And a CSP does not govern navigation or WebRTC, so script could still send the whole page to another address with data in the URL, or open a peer-to-peer connection. Nothing here does any of that, and you can confirm it in the Network tab, but those are the honest limits of what a CSP can promise and I would rather state them than let the stronger claim stand.
What I don't collect
- No tracking scripts, and no telemetry sent from your browser.
- No cookies, so nothing that needs a consent banner.
- No accounts, no sign-in, no email addresses.
- No third-party scripts, fonts or CDNs. Everything is served from this domain.
- No error reporting service that might capture the contents of an input field.
The one thing stored locally
Your light or dark theme preference, in localStorage under the key
cardtools-theme. It never leaves your browser, and clearing site data removes
it. Nothing else is persisted, with one short-lived exception described below.
Opening a tool from the home page
When you paste something into the box on the home page and click the tool it suggests, the
page has to pass what you pasted to the next page. It does that without putting it in the
address, because anything in a URL ends up in your browser history, your address-bar
suggestions and, if you use browser sync, on every device you are signed in on. Instead
the value goes into sessionStorage under the key
cardtools-handoff, and the tool you open reads it and deletes it straight
away.
That entry belongs to the one browser tab, is never synced and never sent anywhere. It is ignored by any page other than the one it was written for, and by that page after two minutes, and closing the tab removes it. The same applies to the "open in" links between tools, such as from a card number inside an ISO 8583 message to the PAN validator.
One side effect: if you open one of those links in a new tab from the right-click menu, the tool opens empty. That menu is also how a link address is copied, and the address deliberately never contains what you pasted.
About "copy link"
Some tools offer a shareable link that embeds your input in the URL fragment, the part after
the #. Browsers never transmit fragments to servers, so this is safe by
construction. But it is only ever created when you press the button: no tool writes your data
into the address bar automatically, so that a value cannot leak into your browsing
history or a screenshot without your say-so. Where the input may be a card number or track
data, the button asks you to confirm before it copies anything.
If you do share such a link, remember that the data travels with it. Do not paste one containing a real card number into a ticket or a chat. When you open a link that carries a value, the page reads it and then removes it from the address bar, so it is not what your history keeps for that page.
Server logs and visitor counts
This site is hosted on Cloudflare Workers. Like any web host, Cloudflare records standard request metadata for delivery and abuse prevention: IP address, timestamp, and which page was asked for. I do look at the aggregate counts that come out of it, meaning how many visits there were and roughly which countries they came from.
That is measured at the edge, from requests the server already receives. Nothing runs in your browser to produce it. There is no tracking script, no cookie, and no identifier tying one request to the next. It is the same information any web server in the world would have by being asked for a page.
It covers the HTML, CSS, JavaScript and font files you download. It cannot include what you type into a tool, because that never becomes a request.
Still, be careful with live card data
Everything above is true, and you should still prefer test data. A real PAN in a browser tab is a real PAN in your clipboard, possibly in a screenshot, and inside a machine that is almost certainly not in your PCI DSS scope. Tools that mask cardholder data on this site do so by default for that reason.
If your organisation has a policy about where cardholder data may be entered, this site is subject to it regardless of how it is built.
Accuracy
The reference data here is compiled from public specifications (EMV 4.x books, ISO 8583:1987, ISO 4217, ISO 3166-1, ISO/IEC 7812) and from schemes' own published acceptance guides. It is reference information, not advice, and scheme rules change. Confirm against your acquirer or scheme documentation before acting on anything you read here.