Risks (or non-risks) of scanning QR codes
Posted by ekr on 20 Feb 2022
I did not watch the Super Bowl but it seems Coinbase bought a super bowl ad that consisted of a QR code floating around your screen. Honestly, I find it kind of soothing—not that I own any cryptocurrency—but the Internet got upset:
Scanning an unidentified QR code that bounces across your screen during the Super Bowl is like going around at the end of a party finishing all the half empty drinks. You can do it, but you'll regret it. And you'll get a lip fungus. But for your computer. It's a whole thing.
— Evan Greer (@evan_greer) 2022-02-13
I am once again reminding you that scanning random QR codes is upsettingly close to plugging a random flash drive you found into your laptop.
Do not do the thing.
— Techni-Calli (@iwillleavenow) 2022-02-13
5 years from now, news will come out that Coinbase’s QR code was the source of the biggest data breach in US history.
— Aaron Parnass (@AaronParnass) 2022-02-13
I wasn't planning on clicking on that QR code, but I'm also rather less
worried about it than others. This post explains why, but first we need to have a clear sense
of what's going on.
As I explained earlier, a QR code
is just a way of encoding digital information. The QR reader on your
device then decodes the QR code into a string of bytes and tries
to figure out what to do with those bytes.
Interestingly, there doesn't seem to be any
really standardized meta-information telling
you what the type of the data is, so typically your device
tried to infer it from the first bytes. For instance, if those
https:// in front of it
then it's presumably a Web address (the technical term here is a URL).
But it really could be any data and hopefully your device
infers what it is correctly.
This situation presents a number of potential security risks (see here for discussion of the privacy risks).
Remote Compromise #
Probably the attack that most people have in mind when they think of the potential dangers of QR codes is that that will result in your computer being compromised. From Iam Waqas in IEEE Computer:
Cybercriminals might embed malicious URLs in publicly present QR codes so that anyone who scans them gets infected by malware. At times merely visiting the website might trigger the downloading of malware silently in the background. Apart from that, they might also send phishing emails containing QR codes that again infect the user’s device with malware when scanned.
This is of course possible, but I don't think a QR code presents a particularly high risk compared to the usual risks you take. At a high level, the QR code could result in your computer being compromised in three basic ways:
The QR code could take you to a Web site that attacks your browser.
The QR code could take you to a Web site that prompts you to install some malicious software.
The QR code reader on your computer/device could itself have a vulnerability that enables compromise.
Let's put (2) aside here for a minute, because while it's a real attack, it really belongs with phishing, which I cover below; this leaves us with attacking the QR code reader and malicious Web sites.
The QR Code Reader #
It's certainly not out of the question that the QR code reader—whether the one built into the device or the one in your browser—could have some kind of vulnerability, as bugs in image processing code are reasonably common. For example, NSO's iMessage exploit took advantage of a vulnerability in the iOS PDF reader (see this excellent writeup by Ian Beer and Samuel Groß of Google Project Zero). With that said, a vulnerability like this in the QR code reader would be pretty serious, given that people scan untrusted QR codes all the time and aren't going to stop.
This isn't to say they don't exist: this article what seem like some legitimate memory vulnerabilities in the Android QR code reader back in 2015. As far as I can tell, the last serious vulnerability in a QR code reader on a major device operating system was actually in the URL parser in iOS 11. This isn't good but shouldn't lead to device compromise.
Note that these comments mostly apply to the QR code reader that is built into your device or your browser. I generally would not assume that a random QR code reader app is safe to use to read arbitrary QR codes. And of course in at least one case a QR code scanner contained malware itself. However, it would be a big deal if the QR code reader built into your phone OS were insecure.
Compromise of the Browser #
This brings me to the second major avenue for remote compromise: the browser. In this case what's happening is that the QR code contains the address of some Web site and reading the QR code navigates your browser to that site, and presumably that site would then attack your computer. This situation isn't conceptually any different from you just typing in the site address yourself: the end result is you end up at a specific Web site that was indicated by the QR code.
One point that is often made in this situation is that it's hard to know what Web site you will end up at because the QR code is unreadable by humans. This is true, but, I think, largely misplaced, for three reasons:
It's common for QR code readers to show you the URL they are going to, so it's not opaque. Indeed, the iOS exploit I mentioned above was designed to circumvent that feature.
You don't need a QR code to send someone an opaque URL: You can just use a URL shortener like bit.ly.
Going to arbitrary URLs shouldn't be a problem anyway.
This first two of these reasons should be straightforward, but the last needs some unpacking. The point here is that it's the browser's job to protect you even from malicious site (indeed, especially from malicious sites). In fact, in a paper with Lin-Shung Huang, Eric Chen, Adam Barth, Collin Jackson, we described it as the "core security guarantee" of the Web: users can safely visit arbitrary web sites and execute scripts provided by those sites. The browser does this by isolating the content provided by the site so that it (hopefully) can't endanger your computer. Of course, browsers do have vulnerabilities that can result in remote compromise, but these are very serious defects that are worth real money: a remote compromise of a live web browser is worth $100K or more. If you have such a vulnerability, there are probably better things to do with it than hack random Super Bowl watchers, especially given that that's hardly an anonymous or stealthy way to deliver your payload.
Even if we assume that you have a zero-day like this and you're willing to waste it in an on attack on basically random people, there are easier ways to accomplish that. For instance, you could serve up your attack via a Web advertising campaign; this would even let you target your victims to some extent, especially if you're willing to pay. Indeed, it's precisely because it's so easy to get a large number of people to load content from your site that it's so important that browsers be safe when run against arbitrary sites.
Probably the more serious risk here is phishing. As with any phishing attack, phishing via QR code relies on you thinking that you are going to a site operated by someone legitimate when it's actually operated by the attacker. How serious this attack turns out to be depends on how much you trusted the person you thought you were connecting to in the first place.
In this case, for instance, you're theoretically connecting to Coinbase and the attacker might try to prompt you for your credit card and banking information or, if you're a Coinbase customer, for your Coinbase credentials (use a password manager, people). Obviously, you need to be careful here, but again, the situation isn't any different than if the attacker had provided a short URL; in both cases you enter something opaque and you end up at a site with a domain you may or may not recognize. Or, for that matter, the attacker might send you to a domain that looks plausible but is not run by who you think it is. For example, http://coinba.se does not take you where you might expect.
One interesting recent example of QR-code based phishing attacks if phishers putting fake QR codes on parking meters. The victim thinks they are paying to park but really they are paying the scammer. This attack seems like it's slightly facilitated by QR codes but mostly it's facilitated by using your phone to pay a parking meter. It's not as if the actual site you go to pay for parking necessarily has a particularly credible looking name anyway, so it's not clear how much better the situation would be if you had to type in a URL rather than a QR code (though obviously it would be less convenient.)
Browsers do try to protect users from this kind of attack using blocklists like Safe Browsing. This actually seems like a case where blocklist techniques are likely to be fairly effective because the time scale of attack is fairly long—the stickers take a long time to deploy and people are fooled over a period of days—which gives the blocklist provider time to detect the attack and mitigate it. By contrast, ordinary phishing attacks (e.g., by email) can use short-lived domains and so be hard to block before they do damage.
Consider the Source #
The final reason I'm not too worried about the Super Bowl ad per se is that it's expensive and easily attributable. A 30 second Super Bowl ad cost as much as $7 million, so you'd have to be a pretty dedicated attacker to use that airtime to deploy your malicious QR code. Moreover, it's hard to buy that kind of thing anonymously, so when people inevitably discover that the QR code is malicious, the attacker is likely to be looking at some pretty serious law enforcement action.
I've seen it suggested that a more interesting threat vector is reposts on YouTube and the like:
"The real risk in this situation is if someone edits the commercial and adds a malicious QR code to it, especially on social media platforms.
People will repost Super Bowl ads for weeks after the game itself, so an attacker could easily change the QR code. The ad could be reposted across social media apps and crypto forums to get people to visit a malicious webpage. That page could be a fake Coinbase login site. If this was a success, the victim could end up having their entire account drained. Attackers could also build that page to deliver a trojanized version of a crypto app.
This does seem like a potential risk, though hopefully most of the major venues for finding the Coinbase ad will actually get the right QR code. Here too, time is on your side and so even if someone does post a fake YouTube video, hopefully YouTube would be able to take it down fairly quickly.
I'm not saying that you should trust that a random QR code that claims to be for your bank actually is legitimate any more than you should trust a random email that claims to be from your bank. However, this just doesn't seem like a particularly efficient mechanism for attack delivery. The parking meter case is interesting precisely because (1) the user may have no real previous association with the service provider and so it's hard for them to know if it's legitimate and (2) the user already has an intent to pay—and is probably in a hurry—so even a very small success rate is likely to be worth the effort of going around sticking stickers on parking meters. The situation for Super Bowl ads seems pretty different.
I'm open to being wrong here, but from what I've seen so far, I'm just not that concerned about this particular threat. However, even if you disagree with me, we have to deal with the fact that users probably aren't going to stop scanning QR codes whatever we tell them; it's up to operating system and browser vendors to make that as safe as we can and/or to offer alternatives that are safer and equally convenient.
This writeup also describes some attacks where you insert JS in the QR code and it gets executed by the client. Those attacks seem to rely on the QR code data being treated as a
file://URL and same origin to other
file://URLs, which is something that browsers are moving away from. ↩︎
Note that in the ads case they'll be loading that data in an IFRAME, but this probably won't make a difference to attack effectiveness. ↩︎
There is no HTTPS version. ↩︎