We can’t end this year without talking about open source package hijacks one more time.
In October this year, the heavily used npm package ‘ua-parser-js’ was hijacked. Then, November began with two other immensely popular npm libraries, ‘coa’ and ‘rc’ getting taken over—all three cases exhibited similarities to malware attacks discovered by Sonatype in the same week.
Now, we’re seeing another hijacked package, ‘qr.js’. But, this incident is a tad different and not a typical “hijack.”
Understanding the qr.js ‘hijack’
A few days ago, I learned about a few concerns, questioning if the ‘qr.js’ library had been hijacked:
On the issue report, Marco Argentieri, co-founder of blockchain company Vulpem Ventures, stated that the GitHub repository for “qr.js” had been taken over and this would put “hundreds of crypto [projects] using this library” potentially at risk. Others believed that the NPM account associated with the library maintainer was compromised.
On digging deeper, however, it turns out, this incident is a live example of what has been previously called “repo jacking.”
Put simply, should a GitHub project owner rename their account, the URLs to their projects would now change to reflect the new username, and the older username becomes available for anyone to claim. And, that can open up the possibility of “repo jacking” attacks, as explained below.
First look at qr.js
Right now, the qr.js npm page shows only one version (0.0.0) exists for the package. And after analyzing our archives, Sonatype can confirm we are not aware of any other version having been published after March 2013.
URLs to the library’s GitHub homepage and repo present on the NPM page, however, start with github.com/shtylman/qr.js. And this URL, as of today, shows a proof-of-concept repo “takeover” notice placed by researcher and bug bounty hunter Codermak.
Understandably, this would have anyone concerned. The official NPM page of a popular library pointing to a GitHub repository that has been hijacked and exhibits no signs of the legitimate “qr.js” existing anywhere near it.
But, analyzing the repository links via the Internet Archive’s Wayback Machine solves the puzzle within minutes.
The NPM page for ‘qr.js’ always indeed link to github.com/shtylman/qr.js. Earliest record of thi has been preserved since at least 2020. In fact, ‘shtylman’ used to be the username of the package’s maintainer. The manifest file, package.json, within the qr.js npm package, continues to contain this URL even today, as seen by Sonatype:
But, today the official GitHub repo for qr.js lives at https://github.com/defunctzombie/qr.js.
The key detail here is just this. After the author of the qr.js library changed their GitHub username from shtylman to defunctzombie, quite sensibly, the link to their GitHub username itself would throw a 404 (Not Found) error, which is the expected behavior. But, the old links to the qr.js GitHub repo itself would redirect automatically to the new location just fine, up until earlier this year:
On November 12th, though, when the bounty hunter grabbed the available ‘shtylman’ username on GitHub, and published their mock ‘qr.js’ repository, any GitHub URLs containing the ‘shtylman’ username would now lead to the new profile and repository location setup by the researcher. And, hence the “takeover” occurs.
What should users do?
Since qr.js, while heavily used, has been unmaintained for over nine years, it might be a good idea to explore an alternate library or include the functional code from ‘qr.js’ directly within your application, rather than pulling in qr.js as a dependency.
Paul O’Shannessy, an engineering manager at Meta (Facebook) opened up another GitHub issue this week—suggesting that the ‘qr.js’ dependency be replaced with better alternative from his qrcode.react project altogether. O’Shannessy writes:
“As noted in qr.js has been hijacked… the original repo was taken over. While this isn't an active issue (that wasn't even the original author of qr.js, npm [account] has not been taken over), it would still be good to find a more stable/modern dependency (potentially vendored to make this a zero dependency install)."
Another engineer and entrepreneur, Mohamed Meabed also updated parts of his react-qr-code project to safeguard future releases.
At the time of writing, there is no indication that the original qr.js version 0.0.0 on NPM is unsafe.
The potential for new versions of the qr.js npm package to be malicious, should they be published in future, is quite low. But, it is the older GitHub repository that cannot be trusted.
Should anyone’s projects be fetching the ‘qr.js’ dependency from github.com/shtylman/qr.js, their builds would no longer work as intended ever since the GitHub account takeover. As such, search for references to the old repo in your project and remove them, or replace them with the newer path to the official repo: github.com/defunctzombie/qr.js.
Sonatype’s world-class security research data, combined with our automated malware detection technology safeguards your developers, customers, and software supply chain from infections impacting open source repositories, including NPM. Users of Nexus Firewall are protected from suspicious NPM and PyPI packages that may appear out of the blue, even while a human researcher review is underway.