Runtime profile on the live @bitwarden/[email protected] supply chain compromise.
Notably, the runtime patterns observed during execution in CI runners match what we saw in recent teampcp incidents (trivy, kics) and shai-hulud 2.0 from november — similar evasion shape, credential-harvesting, and C2 infrastructure.
Field notes and telemetry (developing): https://t.co/5JvG08AznX
We keep seeing things like this.
Nothing obviously wrong from a quick look but runtime behavior during code execution raises questions.
Worth digging deeper.
Came across a newly published npm package eslint-vite (https://t.co/DNj4WQttLE) currently live with:
- only 3 versions
- ~300 weekly downloads
- 0 dependencies
Installed and ran it inside our internal GitHub runner.
At runtime, we observed outbound calls to:
Binance, Aptos, Google Drive, and some other interesting destinations.
The interesting question is: why is a linter making these calls?
Not saying this is malicious, could be benign. But worth keeping an eye on. This kind of behavior is easy to miss unless you look at what actually happens during execution.
Run profile: https://t.co/nWNkVfkISn
@Star_Knight12 Matches what we saw at runtime.
The install spawns a shell, pulls a second stage from an external host, then deletes itself so everything looks clean after.
Hard to reason about this just from the package or lockfiles.
If you’re trying to sanity check whether you were impacted by the axios/npm compromise:
watch the network activity during install.
In the compromised versions, installs reach out to domains outside of npm (like the one in the screenshot). A clean install should only talk to registry[.]npmjs[.]org.
We caught this by running installs in CI and observing egress with Garnet.
If helpful, you can try this in your own CI here: https://t.co/VWpWStpHbK
We looked at the axios npm compromise from a runtime lens by replaying the install in a CI runner and capturing the execution chain.
What actually happens is very different from what the package looks like on disk: a postinstall script from a newly introduced dependency spawns a shell, reaches out to an external host, stages a second payload, and then removes itself, leaving almost no filesystem trace.
Running the same install on a clean version produces none of this behavior. The more useful pattern here is not just catching the compromise, but re-running patched versions and confirming that runtime behavior returns to normal.
Full runtime profile here: https://t.co/3DLRTij8y8
We analyzed the axios npm compromise by replaying the install in a CI runner and capturing the full runtime execution chain.
The observed behavior differs significantly from what is visible in the package itself. A postinstall script from a newly introduced dependency spawns a shell, reaches out to an external host, stages a second payload, and then removes itself, leaving minimal filesystem evidence.
Running the same install on a clean version shows none of this behavior. Same command, different execution.
This is a useful pattern beyond this incident as well. Re-running patched versions and validating that runtime behavior returns to a clean baseline provides a more reliable signal than static inspection alone.
Full run profile: https://t.co/S11DE9wVjI
This is what runtime visibility provides:
A clear, end-to-end view of what actually happened — not just what was expected to happen.
From import → payload execution → network egress → process orphaning, every step is captured and attributable.
That’s what enables true auditability in modern developer environments.
We detonated the backdoored Telnyx SDK inside a GitHub Actions runner and traced its behavior end-to-end (at @garnet_labs ).
What we observed:
- import telnyx triggers a backdoor at runtime
- A base64-decoded payload is executed
- A persistent TCP connection is established to 83.142.209.203
- The parent process exits, but the malicious child continues running (reparented to systemd)
From the outside, the pipeline appears to complete normally.
At runtime, the process is still active.
This kind of visibility is what makes it possible to understand how these attacks actually behave in real environments.
cc: @farrukhkjadoon
We replayed this in our lab.
Same /proc/*/mem scrape, same encryption, same exfil pattern TeamPCP used across 76 Trivy tags.
The job exit code stayed green the whole time.
Full trace → https://t.co/Yh7VtaJCFi
On March 19, Trivy — the scanner your CI trusts to find vulnerabilities — was used to steal your secrets.
Here's what it looked like at the kernel level:
That red domain? scan.aquasecurtiy[.]org — a typosquat of Aqua's own domain. The scanner still reported clean.
This is what we built Garnet for. Not to replace scanners — but to show you what actually ran, regardless of what the exit code says.
Full trace → https://t.co/4i22nvwHW1
In a live hack, we've hooked up our #ebpf agent jibril with @claudeai -- come check it out and see what the future of agentic runtime security looks like! 🧑💻
You can try Jibril free today in your environment: 👉 https://t.co/X7Dh8lrFPz
Check our HN discussion at https://t.co/UhWaG3wfRS, and read more about it in docs
We'd love to hear feedback, use cases and what we can improve on / build next!
🎉 Excited to announce we’ve just launched Jibril on Hacker News!
Jibril is a runtime security monitoring & enforcement tool designed specifically for modern, ephemeral, and cloud-native environments.
Read on for why we decided to build it at @garnet_labs 🧵
Jibril answers the Qs that keep modern platform and eng teams up at night. Some examples:
❓ What network calls did my GitHub Actions test run make (and which dependency made them)?
❓ How do I block memory dump attacks in my CI runner -- like the recent tj-actions incident?
❓ How to auto-block malicious DNS in K8s based on a managed blocklist (including latest known C2s and cryptomining domains)? and automatically update my perimeter-wide firewall rules based on that context?