Why you should never trust an online QR code generator
A QR code is not human readable. That single fact is what the whole attack rests on.
How this site started
This project began because of a simple test. Search for a QR code generator, take the top few results, paste in a Bitcoin address, and compare what comes back. Several of them returned a code that did not contain the address that was typed in. It contained somebody else's.
How the substitution works
You paste your payment address into a website. The site returns a picture. You cannot read a picture of a QR code, so you accept it, put it on an invoice, a poster, a donation page or a business card, and throw away the original text. Every person who scans it pays the attacker instead of you. Nothing looks wrong at any point, and by the time anyone notices, the money is gone and the printed code is already in circulation.
Why it keeps working
- You cannot tell two QR codes apart by looking at them. Neither can anyone you send it to.
- The generator is used exactly once, at the moment the original text is still on screen, and then never again.
- The code often ends up printed, screenshotted or embedded somewhere the original text no longer exists, so there is nothing left to compare against.
- People who do check tend to compare only the first and last few characters. Attackers generate addresses that match those.
The other direction: codes you did not make
This site is mostly about codes you create. Most QR fraud runs the other way. Someone puts a sticker over the code on a parking meter or a payment terminal, or sends an invoice as a PDF with a code in place of a link. The code leads somewhere that looks right and asks you to sign in or pay. The industry calls this quishing, and it works for the same reason the substitution attack does: you cannot see where a QR code goes until you have already gone there.
- Stickers placed over the real code on parking meters, chargers and payment terminals.
- Codes inside emails and PDF attachments, which get past filters that would have stopped a plain link.
- Fake restaurant menus, parcel delivery notices and utility bill reminders.
- Posters and flyers in public, where nobody can tell an added sticker from the original print.
Decode a code and read its destination before you visit it: Check a code
How to protect yourself
- Scan every QR code yourself before you share it, using the device you would actually pay from.
- Compare the entire string, character by character, not just the ends.
- Prefer a generator that works with the network turned off. If it needs a server, the server can change your data.
- Check the address checksum. Bitcoin addresses carry one, and a corrupted address will fail it.
- Regenerate the code yourself rather than reusing one somebody sent you.
- Before scanning a code in public, check whether a sticker has been placed over the original. Physical tampering is the most common version of this.
- Read the whole domain of any link a code leads to, and never sign in or pay from a page you reached by scanning something.
What this site does differently
- The QR code is built in your browser. Nothing you type is transmitted anywhere, because the site has no server to transmit to.
- After drawing the code, the page decodes the image it just produced and shows you what it reads back. If that does not match what you typed, it says so.
- The content security policy allows no external origins at all, so the page cannot load or contact anything, even by accident.
- The whole thing is static files and open source. You can read every line, save the page, and run it offline forever.
Do not take this site's word for it either
Everything above is a reason to distrust QR code generators, and this is a QR code generator. The readback check on the generator page is a convenience, not a proof — it is the same code that drew the image. The only check that really counts is the one you do yourself, on your own device, against your own address. Do that one.
Common questions
Can a QR code generator change my Bitcoin address?
Yes. If the code is generated on someone else's server, that server decides what goes into the image. It can return a code containing any address it likes, and the picture will look completely normal.
How do I check that a QR code contains the right address?
Scan it with the device you would pay from and compare the decoded text against your address in full. Do not compare only the first and last few characters, because an attacker can match those.
Is it safe to use an online QR code generator for a wallet address?
Only if the generator runs entirely in your browser and you verify the result by scanning it. Anything that sends your address to a server is asking you to trust that server with your money.
Does this site send my data anywhere?
No. The page is static and the encoding runs in your browser. You can disconnect from the internet, reload, and it will keep working.
What is quishing?
Phishing that uses a QR code instead of a link. The code hides the destination, so it gets past both email filters and the habit of hovering over a link before clicking it. Stickers placed over real codes in public are the most common form.
How can I tell where a QR code goes before scanning it?
Decode the image rather than opening it. The checker on this site shows you the destination without visiting it, and works on a photo or a screenshot of any code.