Malicious VSCode extensions with more than 45k installs
blog.checkpoint.com
blog.checkpoint.com
“…And now if a [color theme] wants to read your data and send it to a server, it needs a filesystem capability and a network capability. It should be an obvious red flag if a [theming addon] were to ask for those dependencies. And this makes it hard to hide malware.” https://borretti.me/article/how-capabilities-work-austral
The original quote talks about a leftpad dependency but it’s a drop-in substitution to apply it here, too. It’s right there in the screenshot:
const https = require(‘http’)
const os = require(‘os’)
Both of those calls ought to error out with “Error: Network capability not provided” and “Error: filesystem capability not provided”, respectively.As a user, you have no way of meaningfully using this info.
Also it might be good to be more specific. E.g. don't ask for all permissions at once, instead if the app starts talking to telemetry.endpoint.com it has to ask for these specific permissions at that point.
Then the user can see, hey this is requesting access to this particular server, that seems fishy, let's not proceed.
The only real solution I can see is only installing plugins from large trusted entities.
Google could have fixed this by allowing the user to give the app mock permissions instead, e.g. empty or randomly-generated storage, fake camera device, randomly-generated contact list, etc. Third-party solutions that allow this have been around for about a decade, but they do not have the reach that Google does.
There used to be a period where many android apps would explain in the description why they needed certain permissions. Those days are over.
No. You think it is suspicious and install another theme that doesn't request anything.
It might be illustrative that Apple, who usually care a lot about good UX, made this procedure downright painful. When the app is installed it’s fine, but when it tries to use a permissioned resource for the first time that pops up a dialog box. That box is not confirm/deny, but rather sends you to the System Settings window, where you have to find the right category, find the program in that category, select Allow, and then enter your password. It seems like Apple might think the Android permissions system failed in part because they made it too easy to say yes.
They didn't. Google regrouped and renamed the permissions until every normal thing that every application needed became grouped with rare and powerful capabilities.
Except for the ad-based crapware, almost all applications minimize their permissions.
Security is a joke in Linux in default configuration.
> . It should be an obvious red flag if a [theming addon] were to ask for those dependencies
No. Theming addons should not even be able to ask for those privileges.
MacOS also recently started investing more into securing the desktops of developers.
Windows seems shit out of luck in that regards.
https://learn.microsoft.com/en-us/windows/security/threat-pr...
It gets your user's privileges when you run it. It's up to you how you run your programs.
Also there's no "default Linux configuration". There are many distributions, and they have different defaults and approaches.
So it's not "up to me" if the good choice is not practical
The actual solution in that space is Flatpak.
Distros clearly don't allow this and none has this feature or these commands preinstalled by default, nor they are built to be multi-user OSes. :D
You can firewall by process UIDs/GIDs too, and I use that to allow the user access only to the internet and not to localhost or home network, or only to localhost, etc.
That's not the principle of least privilege, that's a user rule, and it isn't necessarily a good one.
I can imagine, for example, a theming add-on which queries a weather API and picks colors based on that, perhaps displaying a nice weather bar in the status line.
Such a theme would need to be granted this privilege, which should ideally be restricted to a hosts list, such that the user could pick another weather endpoint, but the theme can't promise weather and give weather and Google Analytics or your choice of telemetry endpoint.
So it's difficult to modify a Linux system binary, but it's extremely easy to delete or exfiltrate a user file.
This security model might have made sense in the past, but today it's totally outdated since almost all systems, both local and in the cloud, have a single user which is the owner (has sudo).
What did you expect? This is a computer to access and manipulate data, not to consume it as a smartphone.
Call me when a smartphone locked toyware can do 1% of what Emacs can do.
If any, stop using propietary crap to do your daily job.
... which should be locked down by group assignments and file-system permission flags. What the hell am I missing? The POSIX model has worked extraordinarily well for decades. The issue you're describing would be no different in Windows or any other operating system. If you install a malicious program, it can embed whatever protocols and communication channels it needs to exfiltrate any data your user account has access to. It's great to advocate for absolute least privilege in programs, but the only people who want to manage a matrix of permissions for every application the system would be IT managers who don't have to deal with the hassle or the complaints. This is precisely why so many things slip through on mobile. "Ain't nobody got time for that."
The capabilities are there for the people who want to hot glue some elaborate contraptions together, but there is no good UX or DX for doing this in a composable manner for end user consumption.
Yes, if it's executed from a script.
> Does Firefox only get to read and write to ~/.config, ~/.cache and ~/Downloads?
I hear people don't like snaps. https://snapcraft.io/docs/home-interface
A combination of very restrictive globals.local and <appname>.local files added to Firejail + custom apparmor rules allows me to jail applications as well or likely better than is possible on any other platform. Other tools are available that accomplish the same, if either or both of these is not to your liking (firejail has improved greatly with recent versions, if your opinion was formed years ago, but not all default profiles have migrated to restrictive explicit allow policies vs. permissive explicit deny policies yet, and those old policies are a pita to add your own restrictions to).
You could also just live with the default rule sets Firejail and Apparmor ship with, and have less restrictively jailed apps by default, but in many cases sufficiently jailed to prevent access to e.g., your ssh-agent without any additional effort-- in this case jailing is just install firejail+apparmor and create a few symlinks for the applications you want to be jailed (IMO still not a high effort bar; and, there is a single command that will create symlinks for you, for everything firejail ships a default profile for, if you feel comfortable running that).
Nothing that interacts with the Internet or untrusted files has access to anything confidential in my home dir, or anywhere else on my system unless that access is needed (including the named pipe for ssh-agent). None of these applications have network access that don't need it. Apps can only use syscalls that are explicitly listed, cannot gain capabilities beyond the restricted capabilities listed, only have access to the bins necessary to run, can only see existence of processes in their own jail, etc.
If, privileged filesystem or network access isn't required as the rule, I'll add a separate profile with extra privileges, and the default profile will not have that access. E.g., for pdf files, I have 'atril' and 'atril-privileged'. Neither atril profile has network access, nor access to ssh keys, global ~/.cache, etc. The day to day one can only read from a few locations on the filesystem, and can only write to two paths. The privileged one can also read where I save private info like tax information.
Firefox profiles run entirely in tmpfs, with each profile having its own ~/.cache ~/Downloads (the real ~/Downloads contains symlinks to each of the jailed Download dirs), etc. I setup the tmpfs for firefox and chromium with a wrapper script, so I can easily handle data that I want to persist and to work around limitations in Firejail. There are separate launchers (rarely used) for Firefox/chromium which allow persistently modifying the profiles (most firefox config is via user.js and misc sqlite/json files, but I'm unaware of an equivalent for chromium).
DBUS is a pita for jails, though. To prevent escaping your private mount namespace jail, you really have to kill dbus access inside the jail (which requires a private net namespace or disallowing unix domain sockets to be really sure; but sometimes all you can do is add a filter-- Firejail allows for all of these options [with limitations on net namespace support for unpriv users] ).
Another addition to my setup that made it so the above restrictions were more or less transparent is a script that runs as a daemon outside the jails and gets fed filenames and urls from another script that runs inside each jail that is symlinked as e.g., symlink name 'atril' for launching a pdf viewer from within a jail-- the outer daemon script will launch an new jail instance of atril with the file passed from e.g., the thunderbird jail by the helper script inside that jail. For URLs, the same jail instance of firefox is re-used.
[1] Other warts are not having syscall groups like openBSD pledge, so you have to track down new syscalls in each new kernel version to restrict using deny policies (which are more flexible than using explicit allow policies). And, linux capabilities are a mess that really deserves a do-over. You can get root with any of, at least, 6 capabilities. And, so much stuff is crammed into CAP_SYS_ADMIN and CAP_NET_ADMIN, that you effectively lose any granularity in selectively allowing privileged activities.
You can get weaker jails, that are more likely to get in your way, on Linux and other platforms that "just work-ish" though [1].
Default jails on Linux with Firejail really is just install the application and run a single command, to jail everything it knows about. Or just create symlinks manually to be more selective. Not a high bar.
Having the ability to customize means not having to change the way I do things to conform to the whims of some random company. Jails that "just work", but do not allow customization are jailing the user too.
[1] You will need to adjust the way you work to the way the jails are setup by default. Some things you may want to do will not work at all, or not in the way you want them to. Many things will not be as extensively jailed as you might like. Applies to any of, Android, iOS, Firejail, etc., using defaults.
People care.
But not enough to go through AppArmor/SELinux hell.
It's a lot of work.
[1] https://github.com/quentinguidee/gitignore-ultimate-vscode
This is because most OSes use outdated security model where the app gets all privileges by default and poor users have to build containers to revoke them, that's why there is an overhead.
If the extension only has access to project files then all applications launched by it should inherit its restrictions.
Disclaimer: I'm the lead developer.
A theme probably doesn't need access to the project files, but many extensions do. This is much harder to solve than in e.g. Android.
This article also highlighted that automated tools used by VS team are pretty good at catching most of similar issues.
That said, malicious code in VS Code extensions is a problem. I wonder if a GPT could be helpful here. The existing internal systems for detecting malicious code seem lacking.
Hehe. We could probably come up with a dozen similar HN specific adjectives.
Anything known to be wrong with 20/20 hindsight.
However, the way things are going, news of these vulnerabilities / incidents will be used to push through the Codespaces (IDE on the cloud) among enterprises -- and many companies will fall for it.
I guess software engineers and technical experts cannot be trusted anymore to keep their machines safe. :-/
Endless.
Anyway, it could have been me. I don't inspect vim plugins before install, generally.
Security is hard. Even if you're an expert, it's a lot of work.
I use vim so dependencies are explicit. But when using npm packages in work I give dependencies a look before I look anywhere else. An unfamiliar dependency gets looked at. It's easier since npm web browser allows inspecting code.
It's a very imperfect process.
Generally I try to install plugins whose authors I know. And whenever I update them (once a year) I re-read the entire source code. Some small plugins I just integrate in vimrc directly.
I hate to say this but Vim isn't the most secure editor, considering features like modelines which some environments enable by default and an aggressive plugin installing culture.
Emacs and lisp is focused on providing power, not security. These often do not go hand in hand.
The "read the source" argument. It doesn't scale. I don't have 17 lifetimes to study a single release of every bit of software I run.
I really do appreciate Emacs for the introspection capabilities, but it's not a solution to the trust chain issue.
The entire point of this thread is how a chain of trust should be maintained. "Don't run untrusted code" is skipping from the question straight to a hypothetical world where an answer has already been established.
"How to live long" - "don't die".
Were they ever? It's a big set of folks, and while some of them were and are competent an even larger subset isn't.
Throw in a credits or fees system where you can request, for a cost, a none audited package is added to the subset but then it's available for everyone.
For the wider problem of depending on external packages and managers like pip or npm I don't see how anyone could realistically keep up with the scale of releases that would need to be checked. You would need far fewer packages from far fewer sources with far less frequent releases for this to be a viable strategy. That might be nicer for developers for other reasons as well but it's not the world we live in today.
its not about them sponsoring it, that frames it wrong. They news to use it, they have security budgets in the tens of millions, they will already be doing some auditing of their own. A vendor can provide that service to the wider market.
You can also add watchers to check who is allowed to publish new versions ad see when that list changes.
Even without looking at the code you could gather a useful report.
I think we never could in the first place? While we are more cautious than the average user, we might occasionally shoot ourself in the foot. That’s part of our job.
The extensions shown in this example would not have ended up on my machine, simply because of the red flags they come with.
The most recent example was probably Win 11 replacing the status bar and people recommending all kinds of anonymous software on GitHub. It's open source and works so it must be alright.
In addition developer PCs often have more privileges than a typical office worker. That's legitimately useful for our work but also means compromising a developer machine is a bigger risk. We're a nightmare for any organisation that wants proper IT security.
When SEs could be trusted?
We run so much 3rd party code that it would be insane to expect SEs to verify it.
Security industry is also heavy of bullshit
Instead of performing reviews they run some "scanners" and fill checkboxes
Someone already posted here how they were able to use PIP to hijack Google developer machines because on their machines defaults were to resolve to public repo first (even for private packages). Google just closed/ignored the issue because this was engineers problem and official build was setup to resolve correctly (this is my from memory summary)
Suppose it takes a couple of days. Then the developer tries the module. Discovers immediately that the module doesn't solve the problem. That's two days wasted for nothing.
Suppose some module that has dependencies on a huge list of other modules. How long will it take now?
I'm not saying polp isn't valid. But is it practical?
Yes, depends on the org, depends on the org.
Introducing third party dependencies should not be a single person decision.
First thing with a new client is usually some form of a VPN access. Even with open protocols, it's challenging to secure a VPN access. Eg. by default running openvpn with a random config provided by a third party allows the third party to push any network setup they want remotely. There's no whitelist, etc. It takes quite a bit of effort to run openvpn as unprivileged user and make it do all network setup via a trusted setuid helper tool that can do whitelisting of allowed network configurations.
And oftentimes VPN has to be some closed source garbage. Management daemons for these require high privileges and take remote commands on how to reconfigure the network and god knows what else. They also can't deal with any non-basic networking setup. The first such VPN solution I had to briefly deal with (before telling the client that we'll want something secure for both sides and it's going to be a fixed wireguard config), was some Linux binary blob that I checked in ghidra before running, and one of the first things it did was scan the system for USB devices, and it had other hidden (to the end user, probably not to the buyer) remote management functionality absolutely irrelevant to a VPN software.
Devs need to apply PoLP also to the clients. Otherwise it's quite easy to accidentally route networks of multiple different clients together via a dev's machine.
This way I never "forget to turn off the client VPN" and similar BS, and my client files don't get mixed up, etc.
https://github.com/microsoft/vscode/issues/52116
It advocates for treating VSCode extension permissioning like browser extension permissioning.
Of course, it's not a panacea, but it would be lovely to have.
I discovered it when I went searching for a way to disable network access for a particular extension. You can do it, sort of, for VSCode itself, but not for individual extensions.
The point of the article is probably valid, but the article itself seems to be dishonest.
If it's 45k total, that's a very small percentage of all installs.
Exaggerate much?
These "security researchers/products" aren't doing anything more than spreading FUD and trying to sell their own products. Most of the FUD they spread is so widely misunderstood and positioned as if X thousands of machines/developers were "affected". The reality is much different.
In the name of being a good security citizen, please just report these extensions so action can be taken and less copy cats occur. Stop writing about these non-events. The reality of each registry is that there will always be bad extensions/packages/etc. The stewards of each registry work very hard to keep them safe. These types of articles make their lives harder, not easier.
What kinds of things do they do? Any idea how this slipped through? Do you know what the review process entails before a plugin is made available for download?
They verify that submissions meet criteria.
They scan for known malicious code/vulnerabilities.
They work with security researchers to take appropriate action on reports.
They enforce CoC and ToS policy to any that abuse it.
They work with the community to address any unrest.
They continuously monitor for suspicious activity.
They respond to active security incidents.
They work across many security working groups to stay current on best practices, latest standards, newest initiatives.
As to your other questions, this isn't "slipping through". These registries act under a "trust but verify" model. It simply would not scale if they had to manually review all submissions akin to the app store(Zero trust). Most of these registries run on volunteers or small pizza teams.
Every single registry has similar challenges. PyPi just last weekend had to halt user sign-ups and uploads due to these abuses.
You're welcome to sign up for early access at https://coderguard.io/
As I'm currently mainly looking for user feedback
Of course this applies not only to VS Code, but to any other software which allows to install third-party extensions like browsers, Gimp, Inkscape, DAWs like Ableton Live, etc. Their developers do not care about security and do not take measures to protect against malicious extensions.
detecting and preventing exfil attempts in real time is the current sota.
So, what's the point? It's literally worthless. It does nothing to stop capabilities abuse.
The same thing could have happened here with Visual Studio Code. The language nor its popular runtimes are simply not designed for this behavior.
As far as I know Node.js still doesn't have capabilities functionality, which doesn't matter, because how broken Deno's is means they're practically on the same footing.
You can do this to create things like plugin systems, etc, where you know by specification you never want a context to have access to say, making HTTP requests.
So, how they suggest we do this with extensions for Visual Studio Code? The editor, as far as I know, doesn't contain any utilities for inspecting the actual source code of the installed plugin before installing, and instead you would have to use some 3rd party thing for downloading the zip file, then manually inspect the contents, before manually installing from the zip archive.
With a subtitle of "Securing the cloud", it's hard to see how they are securing anything here, besides removing three extensions that may or may not be malicious. They're not actually providing any solution, even though they end with plugging their CloudGuard Spectral product that wouldn't even help in this particular case...
It's odd to call this "the open-source components risk" when the exact same things are true for closed-source...
i think lapce supports wasi plugin but overall ux is not there yet when i last tried.
Also did anyone else notice the timeline at the end of the article where it took 10 days to remove these packages from the repo? I could understand some hesitation if a package has something like debatable telemetry but surely behaviour like obfuscated code should result in an immediate block by default?
Stop using propietary software first, then we will discuss your "security" rants. Perl users have been using CPAN since forever, so did LaTeX users with CTAN. Ditto with Emacs users with ELPA and NonGNU. No issues with addons.
I don't think invoking CTAN as an example is very convincing. It's well known that there are only seven people in the universe who can actually program TeX and they probably have little interest in trying to infect each other with malware.
It’s not just malicious extension authors. Compromised developers of good extensions are just as much, if not bigger, of a risk.
Vim, Emacs, Sublime are all examples of bare products that aren't very special unless you add extensions that could potentially leak data and run arbitrary commands.
the fact that only a couple extensions have been found leaking some data involving only a few thousands installs, it's honestly a very good record if you ask me.
> It’s not just malicious extension authors. Compromised developers of good extensions are just as much, if not bigger, of a risk.
If this is your reason to avoid VSCode, then you should probably start avoiding basically all other code, too. It is after all written by developers, who can and has been compromised. All over the supply chain. Over and over again. And so on.
But yea, hate on VSCode will you.
Access to local folders on the host (though rare) is approved on a needs basis.
> it’s our responsibility to verify
I'd recommend checking of your extensions are from a verified publisher. See https://code.visualstudio.com/api/working-with-extensions/pu...
Is there a money to be made in a company that main purpose would be to provide periodic check on the source code dependencies. So that for a certain amount of payment, you get to submit a list of dependencies and they monitor the source code and give a report with that changes, problems and security issues. So it is like a Source code check as a service.
Cheapest plan starts at 1333 USD per month!
there are multiple implementations for macos. there are multiple implementations for linux. run, don’t walk.
yes, there are tradeoffs. you may even changes your web browsing habits to avoid a tirade of prompts from some random chum bucket. it’s all worth it when one of your eyebrows goes up after some process that tries to make a dns request it doesn’t have any business making. then you hit deny. then you investigate.
now all we need is little snitch for filesystems. maybe we can build it on encrypted fuse mounts.
The 45k dowload extension (Darcula Dark) collects some data that I would define as telemetry, and the python-vscode extension which is clearly trying to hide what it's doing. Now, whether you define telemetry as malicious or not may shape how you feel, but let's be honest, there's a world of difference between sending your OS versions to a telemetry server and injecting obfuscated code.
I'm not saying that's good, just that it makes sense that whatever ecosystem/community spawns from your product, they adopt the same methodology as the main product uses.
This is what happens if you use the first party telemetry module msft provides, but obviously not if you’re just sending random http requests.
- Clear API boundaries that defines what you can do or not, with each API surface being obsessively guarded in terms of what it lets through. Usually leads to secure extensions but hard (if not impossible) to do things the API authors didn't foresee as it's locked down hard. Figma plugins use this approach.
- Give extensions raw access to the host platform, to do whatever they want. This is what VSCode and many others do, which comes with a lot of issues regarding security, but plugin authors can essentially do whatever they want.
The first approach requires a lot of careful consideration, development time and maintenance, while leading also to a somewhat locked down environment. It's more secure, but also limits the usefulness of some extensions.
Microsoft, in their usual lazy fashion, chose the latter approach, probably because it makes the most money sense. Why spend a lot of development time (and money) when you can do it faster and for less money? Some security holes won't lose you a ton of money, but spending N developers building a proper plugin API will for sure cost you a ton of money.
- Give extensions the ability to do whatever they want (in the sense of not requiring them to only call your specific API signatures), but run then in a sandbox, so that they have to ask for access to the internet, filesystem, and so on?
By the way, Figma plugins can also send arbitrary information (such as file contents) to external servers.
That said, I think it's good idea to add to extensions permissions/capabilities security like in mobile apps.
P.S. If the Extension API doesn't have what you need, there are Proposed APIs [3], but you can't use them in published extensions, and sometimes proposals move very slowly.
[2] https://code.visualstudio.com/api/extension-capabilities/ove... [1] https://code.visualstudio.com/api/references/vscode-api [3] https://code.visualstudio.com/api/advanced-topics/using-prop...
Or use VSCodium instead. https://vscodium.com
I don't think the title was deceptive.
Maybe the platform and os can be described as "telemetry", but logging the hostname definitely counts as stealing private data!
Apple by default uses the user's name as host name (eg. "John-Does-Macbook-Air.local"), so you could use this to determine if a specific person has installed your extension.
That is spyware, not telemetry.
The malicious extension could then, once it has determined a specific target user has installed the extension, ship a malicious update.
Name/typo-squatting in inherently malicious as there's intent to deceive. It doesn't matter what code is _currently_ present and that can change at any time.
Besides, think about how you'd maliciously use that telemetry. If the author sees installations coming from intuit.com (for example) then they know they are one auto-update away from having a foothold on a company network with tons of sensitive data. That's a targeted supply-chain attack.
We need to stop treating our dev tools like they are trusted. They are not, and they rely more and more on networks of even less trustworthy code. That VSCOde doesn’t have a proper sandbox or TCB for its plugins is pretty damning.
Innocent == 100% offline and benefiting society. If they need telemetry for a color theme then they are not innocent.
For example go look at any popular "Hello world" type of extension and you'll see many results of extensions in this definition of "name squatting".
i.e. https://marketplace.visualstudio.com/search?term=word%20coun...
VS Code Marketplace has a namesquatting problem. It doesn't always imply malicious intent though.
And telemetry for a fucking color theme? You've got shitting me. Whoever did this is a Grade-A scumbag. It didn't happen by accident and there is no possible benign motivation for it. I hope somebody has reported this to the FBI and other relevant authorities.
Combined with the lack of a proper sandbox or TCB for plugins, having an untrustworthy “marketplace” makes VSCode sound like a disaster waiting to be installed.
Another opinion is that there is plenty of crap on every registry and some are better at surfacing and cleaning up than others.
Similar to the US Navy and ships that are rust-free versus those battling rust. It doesn't affect the performance of those ships, just the perception. Left on for too long could eat away the actual integrity.
Not all problems are the registry's to burden. Trust and quality decisions are very individual for example. There's no same definition used between two people.
To be fair, vim and emacs aren’t any better.
Most of our dev tools are based on plug-in models that have zero security model baked in.
How about notable publisher, verified publisher, # of downloads, rating, reviews, README, GitHub repository, extension icon, project details, repository maintenance, etc?
Having a proper set of API boundaries with security guarantees is the right solution. Even “notable publishers” can get hacked.
I don’t even understand why it’s an open question, tbh.
Name squatting relies on people making a typo and installing your stuff. That cannot be innocent, come on now.
Your link also does not prove anything except that people naively make extensions with the same name that feels cute or easily discoverable to them. I see no name squatting in that list, not in the top 10-20 anyway.
You are thinking of typosquatting. And my example shows people can publish extensions squatting on the same extension name as established ones while also changing other metadata to impersonate or spoof popular ones and confuse users quickly looking to install the extension.