Summary
Togoder Security scanned the npm package readable-stream@4.7.0 on Oct 4, 2026. An AI review of 32 source files produced 1 high, 2 medium, 7 low severity findings. The overall verdict is medium: the findings flag risky but common patterns (dynamic code, unsafe defaults, broad file or network access) rather than confirmed malware.
Findings 10
Suspicious module path manipulation
NPS-1824D882271C
The file replaces the standard 'process' module import with require('process/'), a trailing-slash path that can resolve to an attacker-controlled local package named 'process' instead of the Node.js built-in. This is a dependency-confusion / module hijacking vector that may execute arbitrary code from a malicious 'process' package at import time.
Suspicious module resolution
NPS-0CEF5FA2CB30
The module is required as require('process/') instead of the standard require('process'). The trailing slash could be an attempt to load a local or shadowed module rather than the built-in, potentially allowing execution of malicious code if such a module exists in the resolution path. This is unusual for a legitimate internal stream helper and warrants scrutiny.
Import-time module loading
NPS-7FD832266A44
Top-level require() of process, aggregates, validators, utils, and abort-controller executes on import. The process/ override in particular causes side effects before any pipeline logic runs, making it an install/import-time execution surface.
Use of process.nextTick for deferred execution
NPS-F89DBC7105A7
process.nextTick is used throughout for deferred callback scheduling. This is standard Node.js core stream behavior for error/close emission ordering, not a malicious pattern.
Dynamic module loading
NPS-81EF2F94EC74
Uses require('process/') with a trailing slash and require('../../ours/errors'), '../../ours/primordials', and './utils'. These are internal path references typical of Node.js core stream implementation, not external malicious module loading.
Dynamic code execution via Function.prototype.call
NPS-20074A840E21
FunctionPrototypeCall is used to invoke .then and generator functions dynamically. While this pattern is common in Node.js internals to avoid prototype pollution, it can also be abused to call arbitrary functions. In this context it appears to be legitimate stream handling, but it represents a dynamic invocation pattern that could be a vector if the inputs are attacker-controlled.
Top-level code execution on import
NPS-C4DB8976E507
The file performs module resolution and initialization at import time (requires, globalThis access, class definition). Legitimate for a library, but any package imported by a project will execute this code when the module is loaded, so it is a potential attack surface if the package is compromised.
Dynamic require of internal modules
NPS-A32A96B2E995
Multiple conditional require() calls load core stream internals (./readable, ./passthrough) and '../../ours/util' lazily at runtime. While these are expected in Node core, in a third-party/repackaged context this pattern can be redirected to attacker-controlled paths if the module layout is manipulated.
Duplicate module export assignment
NPS-B47129BF5052
The destroy export is assigned twice: first to CustomStream.destroy and then immediately overwritten with originalDestroy (which is CustomStream.Readable.destroy). This is likely a bug or accidental copy/paste issue that could lead to unexpected behavior. It is not malicious per se, but indicates potential code quality issues.
Potential prototype pollution or unexpected behavior
NPS-A9B5F4D26F58
The Object.defineProperty call on CustomStream adds a promises getter with configurable: true. If CustomStream is a shared object, modifying it could affect other modules. However, this appears to be a deliberate API design, not malicious.
Files reviewed
| File | Verdict | What the reviewer saw |
|---|---|---|
| lib/internal/streams/duplexify.js | medium | The code appears to be a modified/patched version of Node.js's internal duplexify with a suspicious require('process/') resolution, but contains no clear evidence of data exfiltration, credential theft, or backdoor installation. |
| lib/internal/streams/pipeline.js | medium | The file appears to be a repackaged Node.js internal stream pipeline implementation, but the substitution of require('process/') for the built-in process module is a suspicious module-resolution hijack that could load attacker-controlled code, warranting caution despite the rest of the logic being standard stream plumbing. |
| lib/ours/browser.js | medium | The code appears to be a legitimate wrapper for the Node.js stream module, with no malicious patterns such as data exfiltration, credential harvesting, obfuscation, or network requests. Minor concerns include a duplicate export and a property definition, but these are not security threats. |
| lib/_stream_duplex.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/_stream_passthrough.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/_stream_readable.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/_stream_transform.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/_stream_writable.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/internal/streams/add-abort-signal.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/internal/streams/buffer_list.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/internal/streams/compose.js | safe | No malicious patterns detected; the code is a legitimate Node.js stream composition module with no network, filesystem, or process manipulation. |
| lib/internal/streams/destroy.js | safe | This is a standard Node.js internal streams destroy implementation with no malicious code, exfiltration, credential harvesting, obfuscation, or backdoor patterns detected. |
| lib/internal/streams/duplex.js | safe | No malicious patterns detected; this is the standard Node.js internal Duplex stream implementation with only expected require calls and no network, filesystem, process spawning, or obfuscated code. |
| lib/internal/streams/end-of-stream.js | safe | No malicious patterns detected; the code is a legitimate Node.js internal stream utility with standard validation and cleanup logic. |
| lib/internal/streams/from.js | safe | No malicious patterns detected; the code implements a standard Readable stream adapter for iterables with no network, filesystem, process, or credential access. |
| lib/internal/streams/lazy_transform.js | safe | No malicious patterns detected; this is a legitimate internal Node.js stream utility implementing a lazy Transform stream with no network, file system, process, or dynamic code execution behavior. |
| lib/internal/streams/legacy.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/internal/streams/operators.js | safe | No malicious patterns detected; the code implements standard stream operators with proper validation and error handling. |
| lib/internal/streams/passthrough.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/internal/streams/readable.js | safe | This is a legitimate, well-known Node.js internal module (readable streams implementation) with no malicious patterns detected. |
| lib/internal/streams/state.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/internal/streams/transform.js | safe | No malicious patterns detected; this is the standard Node.js internal Transform stream implementation with no exfiltration, credential harvesting, obfuscation, or process/network operations. |
| lib/internal/streams/utils.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/internal/streams/writable.js | safe | No malicious patterns detected; this is the standard Node.js internal Writable stream implementation from the official Node.js source. |
| lib/internal/validators.js | safe | Cleared by Jev triage; no further analysis needed |
Show 7 more files
| File | Verdict | What the reviewer saw |
|---|---|---|
| lib/ours/errors.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/ours/index.js | safe | No malicious patterns detected; the code conditionally exports Node.js stream APIs and does not perform any suspicious network, filesystem, or process operations. |
| lib/ours/primordials.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/ours/util.js | safe | This is a standard Node.js utility module that provides common functions like once, promisify, debuglog, and abort signal handling with no malicious patterns detected. |
| lib/ours/util/inspect.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/stream.js | safe | No malicious patterns detected; the code is a standard Node.js stream module implementation with typical module imports and exports. |
| lib/stream/promises.js | safe | No malicious patterns detected; code is a standard promise-based stream pipeline wrapper with no data exfiltration, credential harvesting, obfuscation, or unauthorized system access. |
Affected version ranges
None of the 3 scanned versions of readable-stream are flagged high or critical. The latest scanned version, 4.7.0, is medium risk. Only versions we have scanned are listed; unscanned versions between them are not covered.
| Versions | Verdict | Count | Range | Top findings |
|---|---|---|---|---|
| 4.7.0 | Needs review | 1 | 4.7.0 | Suspicious module path manipulation; Suspicious module resolution |
| 2.3.8 โ 3.6.2 | No issues | 2 | >=2.3.8 <=3.6.2 | |
| 2.3.7 | Not scanned | 1 | 2.3.7 |
Full list, including published versions not scanned yet: version ranges API.
Scanned versions of readable-stream
Frequently asked questions
Is readable-stream safe to use?
No confirmed malware was found in readable-stream@4.7.0, but the review flagged 1 high, 2 medium, 7 low severity findings for risky patterns worth checking before you rely on it.
Does readable-stream contain malware?
No malware was identified in readable-stream@4.7.0 when Togoder Security scanned it on Oct 4, 2026. A new version can still introduce malicious code, so scan the exact versions in your lockfile.
How was readable-stream checked?
Togoder Security downloaded the published npm package and had an AI model read its 32 source files, looking for install scripts, credential access, network exfiltration, obfuscation, backdoors and crypto-wallet theft. The results are cached by file hash and shown here.
How do I scan readable-stream together with the rest of my dependencies?
Upload your lockfile at https://security.togoder.click/scan or call the API documented at https://security.togoder.click/api-docs. Files that have already been scanned, like the ones in readable-stream@4.7.0, cost nothing.