QR codes are short links printed as pixels
A QR code is not a technology for trust. It is a machine-readable string with no human-readable preview, which is exactly why quishing works on people who would never click the same URL in an email. Here is what a QR code actually encodes, why the phone camera layer is where the risk lives, and how to publish one without turning it into a permanent dependency on a company staying alive.
A QR code is a container. ISO/IEC 18004 specifies how to lay out modules, how much error correction to add, and how to encode bytes into a grid that a camera can recover at an angle, in bad light, with a coffee ring across one corner. What it does not specify, because it cannot, is whether the string inside deserves your trust.
Almost every QR code you scan in public contains a URL. So the useful way to think about a QR code is not as a technology but as a short link with the human-readable part removed. Everything true of short links is true here, only worse, because you cannot read a square before your camera resolves it.
What is actually inside the square
The payload is plain text. Conventions built on top of it tell the scanning app what kind of thing it is:
- A URL, which almost every camera app offers to open.
WIFI:T:WPA;S:network;P:password;;, which many phones offer to join directly.- A payment string, which a banking or wallet app may prefill with the amount.
- A contact card, a calendar event, an SMS with a prefilled recipient and body.
- Plain text with no action at all.
The security surface is not the encoding. It is the automation layer on top: the phone that treats "scan" as "start doing this". A URL in an email sits there until you click. A URL in a QR code is one tap from opening, inside an overlay that often truncates the domain to fit.
Why the physical context does the attacking
The reason quishing works is not technical sophistication. It is that a code inherits the credibility of whatever it is stuck to. A sticker on a parking meter looks like the city put it there. A code on a restaurant table looks like the menu. A code in a package insert looks like the seller's warranty page. Attackers have repeatedly used exactly this: print a code, place it over the real one, collect card details on a page that looks close enough.
Email filters cannot help much either, because a code embedded as an image in a PDF or a message body is not a link a scanner can rewrite or check, which is precisely why QR-based credential phishing moved into corporate inboxes.
The defense is boring and it works: treat a scanned URL like a link from a stranger. Read the domain in full before continuing. Never enter payment details on a page you arrived at by scanning something in the physical world; go to the provider's app or type the domain yourself. If a code is a sticker on top of another sticker, do not scan it at all.
Short payload, denser or sparser code
There is a real engineering reason people shorten URLs before generating a code. Payload length drives the version of the symbol, which drives the number of modules. A 22 character URL fits in a low version with plenty of error correction; a 180 character URL with query parameters and UTM tags needs a much denser grid. Denser grids need bigger print, better contrast, and a closer camera. If the code is going on a business card, a bottle cap, or a poster read from three meters away, the shorter payload scans and the long one does not.
The second reason is repointability. Because the printed pattern is immutable, encoding a redirect is the only way to fix a destination after printing. Vendors sell this as a "dynamic QR code", which is a marketing term for "a QR code containing a short link". There is no dynamic anything in the pixels.
The cost nobody prints on the box
Putting a redirect inside a permanent object stacks two failure modes on one artifact.
- Service death. If the shortener shuts down or loses the domain, every printed copy stops working at once. Google's goo.gl is the canonical case: closed to new links in 2019, with existing links breaking in 2025, taking short links embedded in published papers and printed material with them. See the link rot piece for how this plays out.
- Silent repointing. Whoever controls the account controls the destination row. A code printed on packaging in 2024 can resolve somewhere entirely different today, with no visible change. That is a feature when you fix a typo and a serious problem when the account is compromised or the vendor's contract ends.
This is a limit of our own product too. A forwrd.us code depends on forwrd.us existing. For anything meant to last years - packaging, signage, a plaque, a textbook - encode a canonical URL on a domain you control, and put the redirect logic on your own server where you can keep it alive.
Publishing a QR code responsibly
- Print the destination next to the code. A line of small text saying "forwrd.us/abc goes to example.com/support" costs nothing and removes the blind trust.
- Use your own domain when the object is permanent. Use a shortener when the object is temporary or reprintable.
- Keep error correction high enough for the surface. Codes on curved, glossy, or outdoor surfaces get damaged; a denser payload leaves less room for recovery.
- Test with more than one phone. Camera apps differ in how they parse payloads and how much of the URL they display.
- Do not encode credentials or payment amounts in a code posted in public.
Forwrd generates a QR code for every short link you create, downloadable as PNG or SVG, and every link has a preview page so a cautious scanner can check the destination before continuing. We screen destinations for phishing and malware under our service guidelines, and blocked links stop resolving rather than redirecting. Screening reduces the risk; it does not eliminate it, which is why knowing how to resolve a link yourself is still worth ten minutes of your life.
Frequently asked
Can a QR code itself contain a virus?
No. A QR code is a two-dimensional barcode defined by ISO/IEC 18004 that encodes a string of characters, most often a URL. It cannot execute anything on its own. The risk is entirely in what the string points to and in what your phone does with it automatically, such as opening a browser, prefilling a payment, or joining a Wi-Fi network.
Why are QR codes so effective for phishing?
Because there is no readable destination. In an email you can hover a link and read the domain; a printed square gives you nothing until your camera has already resolved it, and phone scanners often show a truncated URL in a small overlay that people accept without reading. Add a plausible physical context - a parking meter, a restaurant table, a package insert, a poster in an office - and the code inherits the trust of the place it is stuck to, which is why sticker-over-sticker attacks on parking and EV charging payments keep working.
Should I put a shortened URL inside a QR code?
It depends on what you need. A shorter payload means fewer modules and a code that scans reliably at small print sizes or from a distance, and a short link lets you fix a wrong destination without reprinting. The cost is a second dependency: if the shortener dies, every printed copy dies with it, and the destination can be repointed later by whoever controls the account. For a permanent object such as packaging or a plaque, encode the canonical URL on a domain you control.
Do QR codes expire?
The code does not. The printed pattern encodes a fixed string forever. What expires is whatever the string points to: the page, the domain registration, or the shortener. A 'dynamic QR code' is just a QR code containing a redirect URL, so its lifetime is the lifetime of that redirect service, not of the pixels.
Related reading
How to check where a short link goes before you open it
The whole function of a short link is that it hides the destination, so the usual advice to read the URL before clicking does not apply. There are still reliable ways to resolve one without loading the page. Here is what works, what does not, and why an unfurled preview in a chat app is not the same as knowing where a link points.
11 min readExpiring links and click limits: when a short link should stop working
Most short links are immortal by default, which is the wrong default for a one-time invite, a password reset handoff, a webinar seat, or a document you only meant one person to open. Expiry dates and click caps are a small feature with real security value, and a few sharp edges worth knowing before you rely on them.
11 min readWhat forwrd.us logs when someone clicks your link
Every shortener sits in the path of every click, which makes it an analytics checkpoint whether it advertises itself as one or not. Rather than write another piece about other people's logging, here is ours: what a click writes to our database, what it does not, what our hosting layer sees before our code runs, how long any of it lives, and which parts we cannot promise away.
12 min read