|
|
Log in / Subscribe / Register

The many failures leading to the LiteLLM compromise

By Jonathan Corbet
March 27, 2026
LiteLLM is a gateway library providing access to a number of large language models (LLMs); it is popular and widely used. On March 24, the word went out that the version of LiteLLM found in the Python Package Index (PyPI) repository had been compromised with information-stealing malware and downloaded thousands of times, sparking concern across the net. This may look like just another supply-chain attack — and it is — but the way it came about reveals just how many weak links there are in the software supply chains that we all depend on.

A Trivyal pursuit

This story starts with a different project, Trivy, which is a widely used security scanner, distributed under the Apache-2.0 license. As is often the case with these scanners, Trivy releases normally include tests for newly discovered vulnerabilities, so projects that depend on Trivy to detect potential security problems in their code have every reason to want to rerun their scans when a new release is made. Many projects hosted on GitHub thus set up an action so that, when a new release tag shows up for Trivy, new scans are automatically run, just in case Trivy has any new problems to point out.

On March 20, Paul McCarty announced that Trivy had been compromised; Philipp Burckhardt wrote up a detailed report on what was done. Somebody had managed to obtain credentials giving write access to the Trivy repository. This attacker then placed commits with malware in that repository, but they did so without changing any existing branches, avoiding the notifications that would have normally gone out in response to such changes. Instead, a large number of release tags were force-pushed to point to the new commits, which was sufficient to cause other projects to perform automatic Trivy runs.

The Trivy malware was of the information-stealing variety; whenever it ran within a project's context, it would sweep up everything it could get its virtual hands on and send it back to the attackers. Trivy itself was never the primary target; it was just a stepping stone giving access to other projects of interest. Just how many projects this exploit was able to hit may not become clear for some time.

On to LiteLLM

One of the projects that fell into that trap was LiteLLM; specifically, the PyPI credentials of one of its developers (krrishdholakia) were harvested. Those credentials were then used to upload compromised versions of LiteLLM (1.82.7 and 1.82.8) to PyPI, where they would subsequently be downloaded by the large number of people who install LiteLLM each day. Specifically, according to futuresearch, there were 47,000 downloads of the compromised LiteLLM package in just 46 minutes.

The word went out quickly, but the distribution of information was hampered by a set of hostile bots that targeted the LiteLLM GitHub issues (#24512 and #24518) with hundreds of spam comments, creating vast amounts of noise. At one point, people were advised to follow the Hacker News discussion rather than the GitHub issues themselves. The malware on PyPI was taken down quickly, but a lot of damage had been done by then.

The second compromised version of LiteLLM, in particular, used an insidious method to run the hostile code on systems where it was installed. Normally, if one installs a compromised Python program, that program will not be able to do anything until somebody runs or imports it. But when the Python interpreter starts up, it looks in the site-packages directory for files with a .pth suffix, and automatically executes the contents of every one it finds. Normally these files are used to configure Python's import paths and such, but they contain ordinary Python code. The litellm_init.pth file added by the compromised LiteLLM package was thus run anytime a Python interpreter started in the install environment (which may be anywhere in the compromised system if LiteLLM was not installed in a virtual environment), regardless of whether anything from LiteLLM itself was run.

That code, once again, gathered up all of the information it could find, including environment variables, SSH keys, Git credentials, Kubernetes secrets, shell histories, crypto wallets, and more. The whole thing was encrypted, packaged into a tar file, and pushed to a system behind the attacker-controlled litellm.cloud domain. There is no way to know how many of these uploads were done or what was in them — until the attackers make use of what they have learned.

Anybody who may have installed the compromised packages clearly has a significant cleanup job to do, including changing any credentials that might have been exfiltrated. The compromised code, for both Trivy and LiteLLM, has been taken down and should not attack any others, but this episode is far from over.

There are going to be vast numbers of compromised systems out there. It seems unlikely that LiteLLM was the only project that was compromised by the Trivy exploit. We have not heard about the others (with the exception of the telnyx compromise reported just as this article was going out); perhaps the attackers have not yet acted on other credentials that they may have acquired. But the attackers are still out there, and they seem unlikely to sit on any such material for long; expect to hear news of other compromised projects. There is also the matter of all those systems that installed the bad LiteLLM packages; again, there is a wealth of information that will have been collected by the attackers, and they seem likely to want to make use of it at some point.

In the end, this episode represents a multi-level cascading failure. A branch-change notification mechanism was bypassed. A software system meant to improve security instead compromised it. Important credentials were stored where automated exploits could read them, and two-factor authentication was evidently not in use. The protections meant to prevent the uploading of hostile packages failed. The ability of Python packages to add configuration code allowed an exploit to reach beyond the compromised package itself. Any of these failures on their own would have been enough to cause a lot of damage; taken together, then enabled a catastrophic security failure that may have only begun to play out.

Index entries for this article
SecurityPython
SecuritySupply chain
PythonSecurity


to post comments

pth code execution

Posted Mar 27, 2026 21:46 UTC (Fri) by aviallon (subscriber, #157205) [Link] (16 responses)

It seems very weird that these pth files would be allowed to use arbitrary python code!

This sure makes the payload much much worse, as there are tons of packages that use python, some even running as root, and pre-installed!

This is _very_ bad!

Are there plans to change how they are handled?

pth code execution

Posted Mar 28, 2026 4:08 UTC (Sat) by azz (subscriber, #371) [Link]

Something that I've added to my packaging system in response to this is to treat .pth files like suid files - they have to be explicitly listed in the package metadata, and I'll be warned if any new ones are added. There are a few legitimate uses of them but they're very rare, and they incur overhead on every Python invocation so it's good to minimise the number of them anyway,

pth code execution

Posted Mar 28, 2026 14:12 UTC (Sat) by geofft (subscriber, #59789) [Link] (14 responses)

I think (or hope, at least) that it's unusual to "sudo pip install litellm". This is a package that is useful for specific applications with their own complex dependency stack, and most users using it will want to be working inside a virtual environment of some sort, or using a project manager like uv that handles virtual environments behind the scenes, instead of installing things into the systemwide Python environment (either via "sudo pip" or via a package manager). It's an abstraction layer over an LLM provider, so it's not very useful without an API key for some hosted LLM service, anyway.

I actually am of the opinion that it was very sloppy for the attackers to use a .pth file, simply because they're so unusual and easy to detect. If they had stuck the code inside the litellm module to be run on import time, they would have been able to gain almost as much arbitrary code execution - most people who install litellm inside a venv do so because they're about to use it.

Also, in practice, there isn't a reliable trust boundary in Python packaging between installing a package and actually running code from it:

  • For various historical reasons, some of which are arguably good, there's no required correspondence between the package name you install and the name of the module you import. So a malicious package can try to create some other top-level import that you're more likely to import. Of course this can be monitored for, just like .pth files.
  • pip itself is written in Python, and runs in the context of the environment it's installing into, and there historically were bugs where a package being installed could write out a Python file that pip was about to attempt to import later in its own execution. I believe bugs like this are now officially considered outside pip's security model (though they are still bugs).
  • There was another security bug disclosed this week where a malicious package can claim to own files it doesn't own, and thereby delete unrelated files when you uninstall it, even if you never actually run code from the package. If you're inside a venv, pip checks that the files are in that venv, but if you're doing something like "sudo pip," there are no restrictions on where that file can be located. In the end this bug was also deemed sufficiently low severity that it has been publicly disclosed while a fix is in progress.
  • Also, of course, the default behavior of pip is that it is equally willing to build packages from source or install precompiled binaries, and building packages from source is necessarily running arbitrary code on your computer.

pth code execution

Posted Mar 28, 2026 16:25 UTC (Sat) by kleptog (subscriber, #1183) [Link] (13 responses)

Pip uses isolated environments to build packages these days and you can install wheels without running any code from the packages itself. The .pth files however are still a thing either way.

pth code execution

Posted Mar 28, 2026 16:34 UTC (Sat) by geofft (subscriber, #59789) [Link] (12 responses)

pip's "isolated" environment means that it sets up a virtual environment for the build process so that there are no conflicts between build dependencies and the target environment you're installing into. It's not a sandbox against malicious code running at build time.

pth code execution

Posted Mar 28, 2026 22:21 UTC (Sat) by Heretic_Blacksheep (subscriber, #169992) [Link] (11 responses)

I think it's coming to the point where code reuse in the community context is an increasingly problematic security risk. One can't depend on a previously trustworthy library/module will remain so indefinitely. The more dependencies a project depends on, the more likely one of those dependencies will end up compromised. None of the current OSes have consistent behaviors when it comes to protecting information from being accessed by different programs running from the same user. Most, even Apple to some degree, ultimately assume the user knows what they're doing and will happily let program X access the credentials or other sensitive data from program Y without comment.

I don't have an answer here, just pointing out the problem is unsolved. I'm not sure it's even realistic to expect programmers (and packagers) that are generally under time pressure to expect them to audit every time Pandas, or let's pick something bigger and more central: Glibc or GTK, gets updated. Most Linux distro packagers are not qualified to security audit the packages they maintain, if they even have the time. The vast majority of packages in any given Linux distro have probably never received a single security audit upstream let alone for the options the packagers themselves pick. This later quirk has come back to bite pretty much every Linux distro at some point.

pth code execution

Posted Mar 29, 2026 1:03 UTC (Sun) by gerdesj (subscriber, #5446) [Link]

'tis turtles all the way down. Before you know it you are pondering questions like: "I think therefore I am ... rly?"

At some point you have to decide what you trust or at least miss-trust the least and work on from there. One of the nastier aspects of this is that Trivy was trusted by many to do what it says it does and only that. So for many, many people, Trivy was a point of trust and that is quite right, until it wasn't.

I think a possible answer to your conundrum is not a single chain or chains of trust but a braid of trust (just made it up). So you need to really answer the question: "Who guards the guards"? Now that is going to get really complicated, really fast.

At some point you have to decide where you stand on all this stuff and I would suggest that you need to start with a form of business continuity and/or disaster recovery planning, rather than diving straight in with a technical discussion of the supply chain for random applications.

I don't think there will ever be a technical solution that will obviate the need to sit down and really look at the risks as they pertain to you personally and at work and whatever is important to you and work out what to do about them. That's why my home has around £300 worth of fire emergency related stuff in it and may shortly sport a de-fib (£500+). I've looked at a few risks and decided that meh isn't good enough. What I have not tried to do is invent a better heart or rebuild my home out of asbestos which is famously inflammable 8)

pth code execution

Posted Mar 29, 2026 15:30 UTC (Sun) by dilinger (subscriber, #2867) [Link] (3 responses)

> Most Linux distro packagers are not qualified to security audit the packages they maintain, if they even have the time. The vast majority of packages in any given Linux distro have probably never received a single security audit upstream let alone for the options the packagers themselves pick. This later quirk has come back to bite pretty much every Linux distro at some point.

On the other hand, these attacks on libraries are much less likely to affect users of stable distributions that only get updates every 6 months or 2 years. That's not to say they're immune, but a short-lived attack where something gets trojaned and is discovered in the space of a month won't end up in the downstream distribution unless there's some extremely bad timing.

pth code execution

Posted Mar 30, 2026 7:54 UTC (Mon) by taladar (subscriber, #68407) [Link] (1 responses)

It sounds like you are under the impression that old upstream versions mean that the code in stable distros isn't new at the time of their release or the release of updates in stable distros. These kinds of attacks can happen to stable distro patches, backports or similar parts of the chain that are just as new in a stable distro as in an upstream release as well.

pth code execution

Posted Mar 30, 2026 21:10 UTC (Mon) by marcH (subscriber, #57642) [Link]

You missed the "short-lived" and "bad timing" parts. So, the entire comment basically.

Stable distributions less vulnerable

Posted Mar 31, 2026 16:26 UTC (Tue) by rfunk (subscriber, #4054) [Link]

This also makes me think of the discourse around Manjaro’s problems; many there are claiming that Manjaro’s 2-4 week delay compared to Arch doesn’t add any value, but I think incidents like this show that such a scheme can be quite valuable if it can help avoid incidents like this.

pth code execution

Posted Mar 30, 2026 9:43 UTC (Mon) by nim-nim (subscriber, #34454) [Link] (5 responses)

That’s the problem of “good enough” (ie sloppiness) when your software outlives the security context “good enough” was evaluated against.

Realistically language communities should outsource fetching building and installing to language-neutral utilities dedicated to staying ahead of the security curve. Because all this stuff is inherently dangerous and difficult to get right. But that’s inconvenient and it is so easy to hack something that sort of works as long as nobody tries hard enough to compromise it.

pth code execution

Posted Mar 30, 2026 12:33 UTC (Mon) by khim (subscriber, #9252) [Link] (3 responses)

> Realistically language communities should outsource fetching building and installing to language-neutral utilities dedicated to staying ahead of the security curve.

“Realistically”? How many of these “language-neutral utilities” even support the most important platforms: iOS, Android, Windows, macOS? Heck, they don't even support cross-distro development, even when they proudly claim they support “GNU/Linux”!

Language communities would be all too glad to offload the packaging to someone else, but there are no one to pick it up. Going from one or two half-working systems (with most languages mostly using just one) to dozen half-working systems wouldn't reduce cognitive load on developers.

pth code execution

Posted Mar 30, 2026 13:36 UTC (Mon) by nim-nim (subscriber, #34454) [Link] (2 responses)

So, want to list the number of language communities reinventing half-baked and half-secured fetch/build/pack/install toolchains out there (when they are not reinventing several of them in parallel) ? That will be much longer that your “but there are many systems” list. Not to mention the vast majority of the language community installers punt on anything not written in their own language (there are us, everything else is content we do not know how to handle or secure, which is why attackers now pack their malware in images or sound files).

pth code execution

Posted Mar 30, 2026 14:59 UTC (Mon) by khim (subscriber, #9252) [Link]

> That will be much longer that your “but there are many systems” list.

It's not “there are many systems” list, but “there are four systems that MUST be supported by any solution to be taken seriously”.

Because these are four systems that may actually provide you with income.

You may try to ignore half of these, in some cases, if you only care about desktop development or only care about mobile development, but “language-neutral utilities dedicated to staying ahead of the security curve” rarely support even two. As such they are entirely outside of scope of what most novice developers would even consider.

You may like that, you may hate that… it doesn't change the outcome.

That's why Google, thoroughly Linux-centered company, made initial version of Chrome that only worked on Windows (Linux and macOS versions were added later). You go where your [potential] users are.

And as long “language-neutral utilities dedicated to staying ahead of the security curve” ignore that simple rule they are entirely outside of the scope of the solution. They are more of a hindrance than help.

That's why we are using CMake, these days, and not autotools or any other POSIX-only build system. For all the problems with CMake it works and autotools don't work.

The same with all these “half-baked and half-secured fetch/build/pack/install toolchains” tools: they work, some better, some worse, “language-neutral utilities dedicated to staying ahead of the security curve” don't work. Why is it so hard to understand these things?

Maybe in some bright future where Valve or someone else would finally manage to create OS that would become more popular than these four situation would change… but who knows how long would it take?

Till then languages have no choice by to do what they are doing.

pth code execution

Posted Mar 30, 2026 19:55 UTC (Mon) by NAR (subscriber, #1313) [Link]

The problem is usually not with the toolchain itself, but with the packages installed. No toolchain will solve that issue. I mean if there's a single maintainer project out there, the single maintainer's account is compromised and the bad guy uploads malware - from the perspective of the toolchain it will look exactly like a proper new version of the package.

pth code execution

Posted Mar 30, 2026 15:38 UTC (Mon) by geofft (subscriber, #59789) [Link]

> Realistically language communities should outsource fetching building and installing to language-neutral utilities dedicated to staying ahead of the security curve.

I work professionally on uv, a language-specific tool for Python.

What is the language-neutral utility that people should be using instead of uv which is dedicated to staying ahead of the security curve?

(Most of the time when I have heard this claim, it comes with the implicit assumption that 98% of the workflows that people are using language-specific tooling for aren't important, or are actively wrong and the world would be better off if they didn't exist, or whatever. It is technically true that ceasing the vast majority of software development activity is a way to reduce security incidents.)

Download a new version of the application to get new tests?

Posted Mar 29, 2026 11:38 UTC (Sun) by tilt12345678 (subscriber, #126336) [Link] (10 responses)

Quote from the article:
> As is often the case with these scanners, Trivy releases normally include tests for newly discovered vulnerabilities, so projects that depend on Trivy to detect potential security problems in their code have every reason to want to rerun their scans when a new release is made.

According to the documentation [1], "trivy" has the functionality to update the vulnerability databases without updating the application.

These days, it's not a good idea to run :latest of anything in the productive publication pipeline without any review. Some scanner software should be no exception.

[1] https://trivy.dev/docs/latest/configuration/db/

Download a new version of the application to get new tests?

Posted Mar 29, 2026 12:16 UTC (Sun) by marcH (subscriber, #57642) [Link] (8 responses)

> These days, it's not a good idea to run :latest of anything in the productive publication pipeline without any review. Some scanner software should be no exception.

In practice, some "uv.lock" or similar file is added to the repository itself, causing large git pollution due to the constant churn of pinned versions. Maybe this could be in a separate git repo, I don't know. It should but it generally isn't.

Then, some "dependabot" automatically creates a Pull Request with available updates and their changelogs. In theory, maintainers carefully review the changelogs to find anything suspicious. In practice, maintainers overwhelmed by AI submissions and $DAYJOB rubberstamp those PRs.

So this looks like progress in theory. But in practice, less so. There are non-technical issues that technology can only help with but not solve.

https://dl.acm.org/doi/10.1145/3347446 "Surviving software dependencies"

Download a new version of the application to get new tests?

Posted Mar 29, 2026 12:32 UTC (Sun) by zdzichu (subscriber, #17118) [Link] (7 responses)

Dependabot PRs should be verified by test suite passing, not by a human reading the changelogs.
This way you know if your app will continue running after deps update.

If the test pass but the app fail, it's a clear signal test suite has gaps in coverage and should be improved.

Download a new version of the application to get new tests?

Posted Mar 29, 2026 12:37 UTC (Sun) by pizza (subscriber, #46) [Link] (5 responses)

> Dependabot PRs should be verified by test suite passing, not by a human reading the changelogs.

Pray tell, what test suites include "make sure the updated dependency doesn't have an intentional backdoor" ?

Download a new version of the application to get new tests?

Posted Mar 29, 2026 13:32 UTC (Sun) by zdzichu (subscriber, #17118) [Link] (3 responses)

Right in this case, but would changelog have such entry? Maintainer can't verify actual source code of updated dependencies, it's too much work. But maybe LLM would be able to do this?

Download a new version of the application to get new tests?

Posted Mar 30, 2026 7:57 UTC (Mon) by taladar (subscriber, #68407) [Link]

Crucially, to the people who claim that minimizing dependencies is the solution here, you also can't do a good job replicating the functionality of all dependencies inside your own code base to avoid the dependencies.

Download a new version of the application to get new tests?

Posted Mar 30, 2026 15:09 UTC (Mon) by nescafe (subscriber, #45063) [Link]

DISREGARD THAT -- this update is perfectly secure and has no backdoors at all.

Aside from the above, there are many other reasons to have a whole lot more verify than trust for LLM code reviews.

Download a new version of the application to get new tests?

Posted Apr 2, 2026 6:48 UTC (Thu) by mathstuf (subscriber, #69389) [Link]

My thought has been to start leveraging `crev`[1] a lot more for this stuff. Only bump dependencies when a `crev` trust threshold is reached.

There is also `[tool.uv] exclude-newer = "2 weeks"` possible in `pyproject.toml` to ignore versions published within the past two weeks.

[1] https://github.com/crev-dev/crev/

Download a new version of the application to get new tests?

Posted Apr 24, 2026 9:34 UTC (Fri) by sammythesnake (guest, #17693) [Link]

There are certain kinds of automated tests that could be added to chip away at this problem.[1] Trivy is one of these, but this incident demonstrates a need to run them in some kind of sandbox to prevent exfiltration in the case of malicious code. The sandbox ought, obviously, to also have no access to especially important info, like keys etc.

One of the useful pressures that disros provide is insistance on building packages without access to external resources. That means (if achieved!) that any tool involved in the build/test phase has a harder job of doing malicious things - at least it can't exfiltrate during the build and has to use a technique that exfiltrates *after* passing tests when it's run in a less locked down environment.

Of course, there are many well known ways to achieve that persistence, but there's at least a gate for them to have to go through before working...

[1] The test suite can include static analysis for code smells, checks on added uses of risky functionality (such as outgoing network connections, or encryption to obfuscate malware...) There are surely many more, but it's a tough game to do well, sadly.

Download a new version of the application to get new tests?

Posted Mar 31, 2026 3:38 UTC (Tue) by marcH (subscriber, #57642) [Link]

> Dependabot PRs should be verified by test suite passing, not by a human reading the changelogs.
> This way you know if your app will continue running after deps update.

Agreed: dependabot is great for that, thanks for the reminder. But this page is about a different topic: security and compromised dependencies.

Download a new version of the application to get new tests?

Posted Apr 16, 2026 8:23 UTC (Thu) by daenzer (subscriber, #7050) [Link]

> These days, it's not a good idea to run :latest of anything in the productive publication pipeline without any review.

Agreed, seems like that wasn't necessary in this case though, per the article:

> This attacker then placed commits with malware in that repository, but they did so without changing any existing branches, avoiding the notifications that would have normally gone out in response to such changes. Instead, a large number of release tags were force-pushed to point to the new commits, which was sufficient to cause other projects to perform automatic Trivy runs.

One takeaway is that even referencing a specific tag isn't good enough, it must be a specific commit ID (or a signed tag plus the signature hash maybe).

Capability-based programming

Posted Mar 29, 2026 20:13 UTC (Sun) by roc (subscriber, #30627) [Link] (13 responses)

I wonder how much better off we'd be if we used a programming language + runtime + packaging system where every package is inherently sandboxed and all access to the environment requires capability passing.

Imagine, for example, a dialect of Rust with no unsafe code and where the standard library is entirely capability-based. E.g. all the accessible filesystem APIs require that you already have a file or directory handle, and all the networking APIs require that you already have an object representing access to the network (a specific socket, or some set of domains).

That would make some libraries much safer, e.g. if some library doesn't need any network or file access, an upstream compromise can't get access to those things. Or if LiteLLM only needs access to some specific AI service domains, it won't be able to access other attacker-controlled domains.

However, an important question is: how easy is it to exfiltrate data if a library has access to some necessary slice of the network? E.g. if LiteLLM can only access OpenAI's domains, can an upstream compromise exfiltrate data through that? I don't know how that would work out.

Capability-based programming

Posted Mar 29, 2026 23:22 UTC (Sun) by Cyberax (✭ supporter ✭, #52523) [Link] (8 responses)

You're describing JavaScript in a NodeJS VM without exposed filesystem objects.

Capability-based programming

Posted Mar 30, 2026 12:23 UTC (Mon) by LtWorf (subscriber, #124958) [Link] (4 responses)

I think before that java applets had this. Of course it had plenty of ways to escape and one had to update all the time. Unless one was an apple user, then the bugs would remain unpatched for several months at a time and websites could freely access the disk of the visitors.

Capability-based programming

Posted Mar 30, 2026 12:55 UTC (Mon) by iabervon (subscriber, #722) [Link] (2 responses)

I don't remember there being anything in that era where you'd have a program that you run locally that's limited by a sandbox to lack some of your access to features of the local system. Applets were generally hosted remotely, with the only support for running them locally being primarily intended to avoid needing to run a web server in order to test an applet you intended to deploy for remote use, and the normal behavior of the Java VM gave programs the standard library with the ability to write arbitrary content to disk and then run it as a native program. The novel NodeJS thing is that it's easy to have it run local programs without all of the standard library in a sandbox that prevents the program from having or fetching equivalent functionality.

Capability-based programming

Posted Mar 30, 2026 14:37 UTC (Mon) by LtWorf (subscriber, #124958) [Link] (1 responses)

Applets were hosted remotely in the sense that before being on your computer the file needed to be on some server. But that's how browsers work, files don't already exist locally.

Other than that, applets were executables that the installed JRE would execute, but sandboxing them so for example you could not open files from the disk.

I think you are confusing server side java software with applets. Same language, same runtime (kinda) but different permissions.

Capability-based programming

Posted Mar 30, 2026 14:53 UTC (Mon) by iabervon (subscriber, #722) [Link]

No, the difference between server-side (or otherwise local, such as the java compiler) java software and applets is my point: you had applets, which you weren't expected to run from a command line or anything other than a browser, and you had programs, which you'd run from the command line (or a script or something), but you didn't have anything you'd run from the command line or scripting or as a batch job that had restricted permissions, which is what NodeJS (as opposed to the builds of javascript engines inside browsers) supports, in addition to the java-program-like mode of having access to all of the user's capabilities.

Capability-based programming

Posted Mar 31, 2026 0:33 UTC (Tue) by Cyberax (✭ supporter ✭, #52523) [Link]

Java Applets had a braindead security model. It was _not_ capability-based but an ACL-based. With access to privileged functionality granted to certain sections of _code_.

Yes, it was THAT dumb.

So you could break it in a ton of different ways, because you often could control the inputs to privileged code. So you could do TOCTTOU races, type confusions, unexpected implementations of getter/setter methods, etc.

And there were a bunch of true bugs in the JIT implementation.

Capability-based programming

Posted Mar 30, 2026 19:42 UTC (Mon) by roc (subscriber, #30627) [Link] (2 responses)

JS as a language is not at all suitable for this. There are far too many ways for a malicious JS library to mess with other code, e.g. by modifying the global object. A language for this would have to be super strict about ensuring that types are real boundaries --- e.g. that data encapsulation is not a suggestion, but an ironclad guarantee. Rust without unsafe would be the right kind of thing.

Capability-based programming

Posted Mar 30, 2026 19:46 UTC (Mon) by roc (subscriber, #30627) [Link]

I mean, while you can create sandboxed JS environments, for this idea you really want capability-based sandboxing to be the default way everything works, so every library interface is a zero-overhead security boundary.

Capability-based programming

Posted Mar 31, 2026 19:55 UTC (Tue) by Cyberax (✭ supporter ✭, #52523) [Link]

With JS the idea is that the whole sandbox is a security boundary.

Or do you want additional separation within the language itself? This would mean no global state whatsoever. And no concurrent access either.

Capability-based programming

Posted Mar 30, 2026 9:59 UTC (Mon) by epa (subscriber, #39769) [Link]

I guess a pure functional language like Haskell would meet that requirement. If the type of a function is int -> int then it is impossible for it to interact with the external world in any way except to consume memory and CPU (and perhaps to get in an infinite loop and not return). That is, if you forbid escape hatches like unsafePerformIO.

Capability-based programming

Posted Mar 30, 2026 14:47 UTC (Mon) by iabervon (subscriber, #722) [Link]

I'm interested in the idea of giving the main program and packages different standard library object creation abilities. The usual problem with capability-based programming is figuring out what capabilities you want the program to have in useful detail. It might be viable to have a relatively small main program with all the capabilities that has to exercise them and pass the results to the rest of the code, and certainly to any dependencies. If you want to let a library open a file that the user picks, you need to give it the file picker factory to do it, and you need to get the file picker factory from the GUI toolkit that you initialized for access to the filesystem, and the system library "access to the filesystem" object constructed by default refuses to list paths where protected credentials would be. Or you have a command line parser that is given access to the filesystem to turn paths on the command line into objects that can open those paths, and the path objects are passed to dependencies that can't open files just given ordinary strings.

Capability-based programming

Posted Mar 30, 2026 19:48 UTC (Mon) by roc (subscriber, #30627) [Link]

I guess Spectre vulnerabilities is another potential blocker. They sort of killed the dream of PL-only security boundaries.

Capability-based programming

Posted Apr 1, 2026 0:53 UTC (Wed) by cyphar (subscriber, #110703) [Link]

This is not exactly what you described, but there have been experiments (such as gomodjail) in trying to lock down execution of dependencies. I think it's a pretty cool idea, but I think a more practical issue is that a lot of modern languages have the ability to execute arbitrary scripts at compile-time in order to configure builds (this is ironically one of a few examples where Go's (over)simplicity makes it an improvement over Rust's security model). It would be nice if those at least were restricted using seccomp or something similar...

PEP829

Posted Apr 8, 2026 7:51 UTC (Wed) by gedeon (subscriber, #21965) [Link]

For what it is worth, PEP829 (https://peps.python.org/pep-0829/), which proposes transitioning to a .toml-based format instead of those awful .pth files, was introduced shortly after this article was published.


Copyright © 2026, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds