Skip to main content

sniffQR for Android is out now on Google Play. Get it

Frequently Asked Questions

Everything you need to know about sniffQR. Can't find what you're looking for?

Get in touch.

General

What is sniffQR?
sniffQR is a QR code scanner that shows you what is really inside a code before you act on it, and tells you honestly when it cannot be sure. It comes in three forms that share one detection engine: an Android app, a free browser extension for Chrome, Brave, Edge and Firefox, and an iPhone app that is next. The two apps are feature-peers. The extension is free with no paywall of any kind; it does less only where a browser genuinely cannot do more.
Which platforms can I get it on?
The free browser extension is out now, published separately to Chrome (which also covers Brave and Edge) and Firefox; Safari comes later. The Android app is out now on Google Play, and the iPhone app is next. The download buttons on this site stay inactive until a listing is genuinely live: we would rather show you an honest placeholder than a link that 404s. Android needs Android 12 or newer. The iPhone app needs iOS 17 or newer and runs on iPhone and iPad. The extension needs Chrome or Edge 116+, Firefox 140+, or Safari 16.4+. Everything is in English only for now.
What types of codes does sniffQR read?
QR codes only: no barcodes, Data Matrix or other formats, on any platform. Within QR it recognizes eleven payload types and gives each its own result view: URLs (including schemeless bare domains), Wi-Fi credentials, contacts (vCard and MECARD), email (mailto: and MATMSG:, including CC and BCC), phone numbers, SMS, geo coordinates, cryptocurrency, 2FA/OTP setup codes, calendar events, and plain text. Cryptocurrency covers seven URI schemes (Bitcoin, Ethereum, Bitcoin Cash, Litecoin, Dogecoin, Monero and Ripple) plus bare addresses with no scheme at all: a naked bc1…, a legacy 1…/3… address or an 0x… Ethereum address still renders a proper crypto card with an 'Open in Wallet' button instead of being dumped as text. On the apps each type gets a native action: join the Wi-Fi network, save the contact, add the calendar event, dial, text, open a 2FA secret in your authenticator, open a location in Maps, open a crypto address in your wallet, or search the web for plain text. The extension does the ones a browser can do and does not pretend to do the rest.
Do I need an API key to use it?
No. The entire local detection engine runs with no key, no account, no purchase and no network connection: payload parsing, look-alike character detection, brand impersonation, leetspeak, hidden characters, harmful file types, shell commands, the user@host trick, punycode decoding, WebSocket detection, and TLS downgrade detection once a link is checked. An API key is only needed if you want a third-party threat-intelligence service to give a verdict on a URL as well. Those services are optional, off by default, and use your own key. Google Web Risk is in the free tier on every platform; VirusTotal (Premium API key required) and custom threat feeds are Pro features of the apps. Google sets Web Risk pricing and can change it: cloud.google.com/web-risk/pricing

Verdicts

What do the verdicts mean?
There are four: 'Safe', 'Potentially Suspicious', 'Likely Malicious', and 'Unknown'. Individual hops in a redirect chain can also be marked 'Not checked', which is deliberately distinct from 'Unknown'. 'Unknown' is the one worth understanding. It means no enabled service produced a result, or when sniffQR could not confirm where a link goes (a short link not yet checked, or a dead link): the link is not safe, not dangerous, just unverified. On a fresh install with no service configured, 'Unknown' is what every URL returns, and sniffQR says so rather than implying everything is fine.
Does 'Safe' mean a link is guaranteed safe?
No. 'Safe' means none of the checks you use found a known threat. Our verdicts work like a traffic light so they are quick to read, not as a guarantee. Sites can be hacked and new scams can slip past any service, so stay alert.
Why does it say 'Unknown' instead of 'Safe'?
Because a 'Safe' verdict requires a threat-intelligence service to have actually said so. That rule is enforced at more than a dozen points in the code: no service configured, every service skipped or errored, a URL that could not be canonicalized for offline matching, an offline database that has never synced, VirusTotal having no report for a URL, or a destination that never answered: all of them report 'Unknown' or Skipped, never 'Safe'. When hops are combined, 'Unknown' outranks 'Safe', so a single hop that could not be checked pulls the whole result down rather than being outvoted by clean ones. sniffQR would rather tell you it does not know than tell you you are safe.
Will it stop me opening something dangerous?
It will always ask first. Only a true 'Safe' verdict opens without a confirmation. 'Potentially Suspicious', 'Likely Malicious' and 'Unknown' all raise one, as does a 'Safe' result that carries a local warning. The dialog says which case you are in rather than using one generic warning, and the button labels never change into an "Open Anyway" dare. One more rule at the moment of opening: only http and https links are handed to the system directly. Any other scheme goes through the share sheet instead, so an exotic scheme hidden in a QR code can never be launched verbatim by a single tap. sniffQR is an informational tool, not a security guarantee. A 'Safe' verdict is not a promise, a 'Likely Malicious' verdict can be a false positive, and new threats may not be in any database yet.
Does a local warning make something Malicious?
No. Local heuristics cap at 'Potentially Suspicious': nothing found on your device can produce a 'Likely Malicious' verdict on its own. On a URL, only the user@host trick (a deterministic structural fact) can lift an 'Unknown' to 'Potentially Suspicious'. Look-alike characters, brand resemblance, hidden characters, harmful extensions and shell commands are all still shown as reasons; they simply do not manufacture certainty in the absence of a service verdict. On payloads no service can vet anyway, such as Wi-Fi or contacts, any local finding does lift the verdict. Some things are deliberately shown without changing the verdict at all: a long redirect chain and a chain that hit the hop limit. A dead destination can only turn 'Safe' into 'Unknown', never into a warning. A dead link is usually just a dead link, and crying wolf cheapens the warnings that carry real evidence.

Security

How does threat scanning work?
The scan runs in a fixed order, and the order is the point. Whatever the source (camera, a photo, or the clipboard), the content is parsed and every local check runs first, with zero traffic to any threat-intelligence service. The link then goes to the services you turned on. Its own website is contacted only when you tap 'Check where this goes' or 'Preview Safely in App', or turn on 'Check links automatically'. With automatic checks on, a link that redirects shows you the chain first and you tick which URLs may be checked; a tap checks the URL you scanned, the final destination and any flagged hop. The extension has no review step: it checks the link you scanned, and the final URL once you check where it goes. The services you enabled then run in parallel with your own keys: Google Web Risk, and on the apps with Pro, Google Web Risk (Offline), VirusTotal, and up to 8 custom threat feeds. A service you turned on always runs: if its key is missing or rejected you get an honest failure row, never a silent drop.
What is redirect chain analysis?
Shortened links hide their destination, so when you tap 'Check where this goes', sniffQR follows the chain and shows you every stop with its own verdict marker. In the apps the probe is a GET whose body is never read; the extension sends a HEAD and falls back to GET. HTTPS to HTTP downgrades stop resolution and become a warning. A redirect that points at something like example.net@evil.example, which makes browsers throw, is recovered so the trick can be shown to you. Any hop resolving to a loopback, private, link-local or carrier-NAT address is refused outright. The free tier follows one hop; Pro follows 1 to 15, defaulting to 5. sniffQR follows the chain only when you tap 'Check where this goes', or turn on 'Check links automatically' (free, off by default). Until then the link's website is never contacted, and a short link reads 'Unknown'. The local analysis still runs in full. The extension works the same way. When it checks, the browser follows the chain and hands an extension only the entry and final URL, so it says "via redirect chain" instead of claiming a hop count it cannot know, and points at the apps for full per-hop detail.
What does 'Preview Safely in App' do?
On Android it opens the link in an ephemeral Chrome tab (Chrome 136 or newer): a throwaway session with none of your cookies, logins or history, and nothing kept afterwards. When Chrome cannot provide one, or the link's address cannot be checked first, it opens sniffQR's own in-app browser instead, with its own empty cookie jar that is wiped when the preview closes. It never opens your regular Chrome session. On iPhone the preview is Apple's in-app Safari view, which keeps its data separate from Safari. The browser extension opens the link in a normal new tab, because an extension cannot isolate one. In every case the link's website is contacted and sees your device's IP address, as opening the link would. On Android, sniffQR's own in-app browser also tells each site the page was opened from sniffQR, because Android adds that to every request; Chrome's tab does not.
How does it detect fake domains that look real?
This is the homoglyph, or IDN homograph, attack: Cyrillic "а" (U+0430) is visually identical to Latin "a", and the same is true of е, о, р, с and many more. An attacker registers a domain using them and the URL looks perfect. sniffQR checks a curated set of confusable characters across five scripts (Cyrillic, Greek, Armenian, Georgian and Cherokee), plus a compatibility fold that catches full-width and fancy-font spoofs like a mathematical-bold rendering of an everyday name. Each finding names the script and the official Unicode character ("Cyrillic а looks like Latin a", CYRILLIC SMALL LETTER A), and a character with no authoritative name reports no name rather than a guess. The real punycode form is shown next to what you saw. Separately, well-known brands are checked four ways: leetspeak and digit substitution (examp1e.net), confusable substitution (exаmple.com), typo-squats one edit away (exampel.org, examplle.org), and subdomain impersonation (example.com.evil.example). Legitimate domains written entirely in one script stay clean. All of this runs on every payload type, not just URLs: Wi-Fi network names, contact-card fields, email addresses, crypto addresses and plain text, plus every URL in the redirect chain. It is free on every platform.
Does it work offline?
Scanning, parsing and the entire local detection engine work with no connection at all. On the apps, Pro adds Google Web Risk (Offline), which downloads short hash prefixes to your device and matches them locally. If a possible match is checked with Google, only a short piece of the link's fingerprint is sent, never the link itself. Because a partial fingerprint can collide, a possible match waits for you to check it with Google, or is checked automatically if you choose, and an unchecked one never reads 'Safe'. You start the first download; after that the list updates itself while the app is open and online. There is no background sync. List updates are free. Checking a match with Google is not free. Use a different billing account than your online key, or online checks stop being free too. Pricing: cloud.google.com/web-risk/pricing The extension has no offline mode: an MV3 extension cannot hold or background-sync that database.

Privacy

Is my data sent to your servers?
No. There is no Apogaeum Labs server to send it to. No account, no login, no analytics, no telemetry, no advertising SDKs, no advertising identifier. Scan history lives on your device, with sensitive fields encrypted at rest using per-field AES-256-GCM on both apps, and excluded from cloud backup and device transfer. Exactly three kinds of thing can leave your device, and you control all of them: a URL to a threat-intelligence service you enabled with your own key; the payload to a custom threat feed endpoint you configured; and, only when you ask, a request to the scanned link's own host to see where it really goes, or to open it with 'Preview Safely in App' in the apps. With Pro's offline mode, list updates and match checks also go to Google, never the link itself.
What leaves my device by default?
Nothing. sniffQR contacts a link's own website only when you tap or click 'Check where this goes', or turn on 'Check links automatically' in 'Settings > Redirect Analysis' (free, off by default, in the apps and the extension). Opening a link with 'Preview Safely in App' in the apps contacts it the same way. That website then sees your IP address, just like opening the link would. The depth controls are Pro: free checks follow a single hop and Pro follows 1 to 15. The extension cannot show you the hops in between, because a browser hands an extension only the entry and final URL. Everything else is opt-in too: no scan content goes to any threat-intelligence service unless you turn one on.
What does VirusTotal receive?
Only an irreversible SHA-256 hash of the URL, as lowercase hex. VirusTotal's API also accepts the URL itself base64-encoded; sniffQR forbids that form on every platform, because it would hand over the full plaintext URL on every lookup. sniffQR also never submits. An earlier build POSTed unmatched URLs to VirusTotal. That does not merely ask a question: it enters the URL into VirusTotal's public corpus, where their scanners fetch it (which can burn a one-time or tokenized link outright) and customers can search and download it forever. That path is deleted. The honest cost is that a hash reveals nothing about a URL VirusTotal has never seen, so sometimes there is no report. sniffQR then says 'Unknown' rather than inventing a verdict.
Are contact, Wi-Fi, calendar, crypto and 2FA codes ever sent anywhere?
By default, no. Contact cards, Wi-Fi, calendar, crypto and 2FA codes make zero network contact (nothing inside them is resolved or checked), and they are never sent to a custom feed at all, on any platform. On the apps, one Settings switch (off by default) lets you opt in to checking web links found inside them, and tells you plainly that doing so reveals the link. Separately, email recipient domains and the addresses inside a contact card are checked for brand impersonation locally, and those domains are never resolved or sent anywhere.
What data does sniffQR collect?
None by the app itself. We hold only the email you send us, the store's order records if you buy Pro, and our website host's standard server logs. Scan history is stored locally on your device and we have no access to it. If you have opted in to share diagnostics with developers in your device settings, Google (on Android) or Apple (on iPhone) may pass us anonymized crash reports. That is controlled entirely by your device settings, contains no scan content or API keys, and can be switched off at any time. If you email us, we get your name and email address, and use them only to reply.
Is sniffQR GDPR compliant?
Yes. Because everything is processed on your device and we hold no personal data apart from email you send us, the store's order records if you buy Pro, and our website host's standard server logs, most rights under GDPR and UK GDPR, CCPA/CPRA, PIPEDA, LGPD and POPIA are satisfied by default; the rest you exercise directly in the app or by uninstalling, or by emailing us. Personal information sold in the preceding 12 months: none. Collected: the name and email address of people who emailed us, store order records from people who bought Pro, and the host's standard server logs. See the Privacy Policy for the full text.

Pricing

Is sniffQR Pro a subscription?
No. sniffQR Pro is a one-time purchase: no recurring charges, no renewal, no expiry date. On Android it is a Google Play one-time product; on iPhone it is a non-consumable App Store purchase. Restore Purchases is available on both. The price is shown in the app and on the store listing, in your own currency.
Is the free tier actually useful?
Yes, and that is deliberate. Free includes the entire local detection engine, all eleven payload types with their native actions, camera scanning, scanning a copied link or copied text, 'Check where this goes' (one hop), Google Web Risk online with your own key, 'Lock on Exit', clipboard auto-clear for copied secrets, the security glossary, the setup guides, and the honest-Unknown verdict system. Pro adds reach rather than turning the safety features on: up to four codes in frame instead of one, photos and images, pinch-to-zoom, deeper redirect chains, unlimited history with export and 'Smart Rescan', Google Web Risk (Offline), VirusTotal (Premium API key required), custom threat feeds, and crypto clipboard-hijack detection.
What happens to my old scans on the free tier?
Nothing. They are kept. The free tier shows your newest 5 scans, but that is a visibility cap, not a retention cap. Older scans stay on your device and reappear the moment you upgrade.
How do refunds work?
Through whichever store you bought from, and we never process payments directly. Android purchases are refunded through Google Play; iPhone purchases through Apple. Or email support@sniffqr.com and we will help. See the Terms for detail.

The browser extension

What does the free extension actually do?
It runs the same checks as the apps: look-alike characters with script identification, brand impersonation, leetspeak, hidden characters, harmful file types, shell commands, user@host, punycode, WebSocket and TLS downgrade. All eleven payload types get the same result cards, the same verdict labels, the same reason rows and the same open-confirmation gate. You can upload an image, drag a box around a QR code on screen, or paste an image, a link or text. Google Web Risk lookups work with your own key, off by default. Crypto payloads get 'Open in Wallet', including bare addresses. It is free with no paywall and no entitlement code of any kind.
What can the extension not do, and why?
VirusTotal and custom threat feeds are deliberately app-only, a product decision stated plainly rather than hidden. The rest are platform limits. There is no offline threat database because MV3 cannot hold or background-sync one. There is no per-hop redirect chain because a browser only exposes the entry and final URL to an extension. There is no camera scanning. There is no persistent history or export: the extension keeps a single verdict in extension storage just long enough to show it, then deletes it. It cannot join a Wi-Fi network, add a contact or open an authenticator, because the browser sandbox cannot. And it cannot check for crypto clipboard tampering, because the browser clipboard is not the OS clipboard. It also does not scan pages automatically and has no right-click scanning. There are no persistent content scripts: the only thing ever injected into a page is the snip selector, and that is injected on demand under the activeTab permission at the moment you invoke it, not sitting on every tab you open.
Do I get the same verdict in the extension as in the app?
Yes, and it is checked mechanically rather than promised. Before every release, the same set of real QR payloads is run through every platform and the results are compared. Android against iPhone must match exactly. The extension's only differences are browser limits, each with a stated reason: the browser cannot see intermediate hops, and it has no offline database or VirusTotal by product decision. Nothing is forgiven for convenience. Both apps run one shared engine, which is why the answers are identical rather than merely close.

Still have questions?

Can't find the answer you're looking for? We're here to help.

Free to start · No subscription · Privacy first