It isn’t news that the overwhelming majority of ad blockers in Chrome Web Store is either outright malicious or waiting to accumulate users before turning malicious. So it wasn’t a surprise that the very first ad blocker I chose semi-randomly (Adblock Web with 700,000 users) turned out malicious. Starting from it, I found another malicious extension (Ad-Blocker, 700,000 users) and two more that have been removed from Chrome Web Store a year ago (BitSafe Adblocker and Adblocker Unlimited).
All these ad blockers and probably some more were developed by the company PCVARK. According to Malwarebytes Labs, this company specializes in developing “potentially unwanted programs.” In other words: they show users warnings about alleged compromise, only to push them into installing their software. Once installed, this software will attempt to scare the user into installing more crappy applications and into paying money for fixing the supposed issue.
While PCVARK originally specialized in Mac software, they apparently also discovered pushing malicious ad blockers to Chrome Web Store as a valuable business opportunity. This was encouraged by Google’s lax moderation policies as well an almost complete lack of policy enforcement. While Google eventually managed to remove some extensions, at least two remain despite being obviously related to the removed ones.
Two days ago I wrote about the malicious extensions I discovered in Chrome Web Store. At some point this article got noticed by Avast. Once their team confirmed my findings, Google finally reacted and started removing these extensions. Out of the 34 extensions I reported, only 8 extensions remain. These eight were all part of an update where I added 16 extensions to my list, an update that came too late for Avast to notice.
Note: Even for the removed extensions, it isn’t “mission accomplished” yet. Yes, the extensions can no longer be installed. However, the existing installations remain. From what I can tell, Google didn’t blocklist these extensions yet.
Avast ran their own search, and they found a bunch of extensions that I didn’t see. So how come they missed eight extensions? The reason seems to be: these are considerably different. They migrated to Manifest V3, so they had to find new ways of running arbitrary code that wouldn’t attract unnecessary attention.
Update (2023-06-03): These extensions have been removed from the Chrome Web Store as well.
Two weeks ago I wrote about the PDF Toolbox extension containing obfuscated malicious code. Despite reporting the issue to Google via two different channels, the extension remains online. It even gained a considerable number of users after I published my article.
A reader tipped me off however that the Zoom Plus extension also makes a request to serasearchtop[.]com. I checked it out and found two other versions of the same malicious code. And I found more extensions in Chrome Web Store which are using it.
So now we are at 18 malicious extensions with a combined user count of 55 million. The most popular of these extensions are Autoskip for Youtube, Crystal Ad block and Brisk VPN: nine, six and five million users respectively.
Update (2023-06-01): With an increased sample I was able to find some more extensions. Also, Lukas Andersson did some research into manipulated extension ratings in Chrome Web Store and pointed out that other extensions exhibited similar patterns in their review. With his help I was able to identify yet another variant of this malicious code and a bunch more malicious extensions. So now we are at 34 malicious extensions and 87 million users.
Update (2023-06-01): Good news: Google started removing these extensions. By the time I published my previous update, a bunch of the extensions mentioned there were already gone. Right now, only nine extensions from this list remain in Chrome Web Store, and these will hopefully also be dealt with soon.
Update (2023-06-02): Google removed one more extension, so only eight extensions remain now. These eight extensions are considerably different from the rest, so I published a follow-up blog post discussing the technical aspects here.
The PDF Toolbox extension for Google Chrome has more than 2 million users and an average rating of 4,2 in the Chrome Web Store. So I was rather surprised to discover obfuscated code in it that has apparently gone unnoticed for at least a year.
The code has been made to look like a legitimate extension API wrapper, merely with some convoluted logic on top. It takes a closer look to recognize unexpected functionality here, and quite some more effort to understand what it is doing.
This code allows serasearchtop[.]com website to inject arbitrary JavaScript code into all websites you visit. While it is impossible for me to tell what this is being used for, the most likely use is injecting ads. More nefarious uses are also possible however.
Update (2023-05-31): As I describe in a follow-up article, this extension isn’t alone. So far I found 18 malicious browser extensions using similar code with a combined user count of 55 million. It’s also clear now that these extensions are at the very least being used to redirect search pages.
These days it’s typical for antivirus vendors to provide you with a browser extension which is meant to improve your online security. I’ll say up front: I don’t consider any such browser extensions recommendable. At best, they are worthless. At worst, they introduce massive security issues.
As an example I took a brief look at the Online Security extension by ReasonLabs. No, there is no actual reason beyond its 7 million users. I think that this extension is a fairly typical representative of its craft.
TL;DR: Most Online Security functionality is already provided by the browser, and there is little indication that it can improve on that. It does implement its functionality in a maximally privacy-unfriendly way however, sharing your browsing history and installed extensions with the vendor. There is also plenty of sloppy programming, some of which might potentially cause issues.
A month ago I announced the end of PfP: Pain-free Passwords. But I’m allowed to change my mind, right? Yes, PfP will be developed further after all. However, it’s so different that I’m publishing it as a new browser extension, not an update to the existing extension.
Rather than using its own data format, PfP 3.x reads and writes KeePass database files. In order for the extension to access these files, users have to install a PfP Native Host application. This application provides access to the configured database files only.
Also, PfP 3.x no longer generates passwords on the fly. All passwords are stored inside the database, and generating passwords randomly happens when passwords are added. While this makes recovery more complicated, elsewhere it simplifies things a lot.
I am by no means a Rust expert, and I’m no expert on declarative macros. I was merely solving an issue I had: there was a lot of redundancy in the way my error types were coded. I didn’t want to repeat the same coding patterns all the time, yet the types also seemed too heterogenous for declarative macros. And going with procedural macros wasn’t worth the effort in this case.
After some experimentation I figured out how declarative macros could work in this scenario after all. I doubt that this approach is very original, and maybe I solved something in a sub-optimal way. I couldn’t find any helpful online sources however, which is why I’m documenting this in my own article. Edit: After publishing this article, I found that the pattern used here is called TT munching.
I’ve been playing around with KeePass databases. One aspect was rather surprising: given how many open source products use this format, it is remarkably underdocumented. At best, you can find outdated and incomplete descriptions by random people. The KeePass developers themselves never bothered providing complete documentation. All you get is a semi-intelligible list of changes from KDBX 3.1 to KDBX 4 and from KDBX 4 to KDBX 4.1. With the starting point not being documented, these are only moderately useful.
And so it’s not surprising that the implementations I looked at aren’t actually implementing the same file format. They all probably manage to handle common files in the same way, but each of them has subtle differences when handling underdocumented format features.
I’ll try to explain the format and the subtle details here. For that, I looked at the source code of KeePass, KeePassXC, keepass-rs Rust library and the kxdbweb JavaScript library. Let’s hope this documentation helps whoever else needs to work with that file format, and studying source code will no longer be required.
I can only document the latest version of the format (KDBX 4.1), though I’ll try to highlight changes wherever I’m aware of them.
Seven years ago I created a password manager. And a few days ago I pushed out the last release for it, notifying users that nothing else will come now. Yes, with the previous release being from 2019, this might have been obvious. Now it’s official however, PfP: Pain-free Passwords is no longer being developed.
I certainly learned a lot from this adventure, and I really like the product which came out of this. Unfortunately, a password manager is a rather time-consuming hobby, and my focus has been elsewhere for a while already.
This doesn’t mean that PfP is going away. In fact, it will probably work well for quite a while until a browser change or something like that makes it unusable. Sync functionality in particular depends on third parties however, and this one already started falling apart.
This little adventure began with me being annoyed at DMARC aggregate reports. My domain doesn’t have enough email traffic to justify routing DMARC emails to some third-party analytics service, yet I want to take a brief glance at them. And the format of these emails makes that maximally inconvenient: download the attachment, unpack it, look through some (always messy but occasionally not even human-readable) XML code. There had to be a better way.
This could have been a Thunderbird extension, processing the email attachment in order to produce some nicer output. Unfortunately, Thunderbird extensions no longer have this kind of power. So I went for another option: having the email server (OpenSMTPD) convert the email as it comes in.
Since I already had the implementation details of OpenSMTPD filters figured out, this wasn’t as complicated as it sounds. The resulting code is on GitHub but I still want to document the process for future me and anyone else who might have a similar issue.