# @tybys/wasm-util@0.10.2 security report (npm)

- Verdict: **Needs review** (risk level: medium)
- Scanned: 2026-10-06T14:12:29.000Z
- Files reviewed: 30
- Findings: 1 high, 4 medium, 11 low severity findings
- Report: https://security.togoder.click/npm/@tybys/wasm-util@0.10.2
- Source: Togoder Security (https://security.togoder.click), AI source-code review

## Summary

Togoder Security scanned the npm package @tybys/wasm-util@0.10.2 on Oct 6, 2026. An AI review of 30 source files produced 1 high, 4 medium, 11 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

### [high] Path Traversal / Sandbox Escape Risk

Finding ID: `NPS-06AD20C9AFD6`

File: `lib/cjs/wasi/preview1.js:123`

`resolvePathSync` and `resolvePathAsync` use a custom `resolve` function from `./path`. While intended to confine paths to preopened directories, the implementation relies entirely on this custom resolver. If `path_1.resolve` does not correctly handle edge cases (e.g., `..` sequences, symlinks, absolute paths), a WASI guest could escape the sandbox and access files outside its preopened directories. Many `path_*` syscalls (e.g., `path_create_directory`, `path_unlink_file`, `path_rename`) directly use this resolver before calling Node's `fs` methods. A flaw here would allow file system manipulation outside the intended scope.

### [medium] Weak Random Number Generation

Finding ID: `NPS-ADC3CE408348`

File: `lib/cjs/wasi/preview1.js:620`

The `random_get` implementation falls back to `Math.random()` when `crypto.getRandomValues` is unavailable or when the WebAssembly memory is backed by a SharedArrayBuffer. `Math.random()` is not cryptographically secure, which can lead to predictable random values for WASI applications relying on `random_get` for security-sensitive operations (e.g., key generation, nonces).

### [medium] Dynamic Module Require

Finding ID: `NPS-6EE0626D78BD`

File: `lib/cjs/wasi/util.js:70`

The code contains logic that dynamically resolves a native `require` function, attempting to bypass bundlers via `__non_webpack_require__` and `__webpack_public_path__`. While this is often used for legitimate compatibility with bundlers, it is also a common technique in malicious or obfuscated packages to hide module loading from static analysis.

### [medium] Insecure Random Fallback

Finding ID: `NPS-DEE7241EFD4A`

File: `lib/mjs/wasi/preview1.mjs`

The random_get implementation falls back to Math.random() when crypto.getRandomValues is unavailable or when operating on SharedArrayBuffer memory. Math.random() is not cryptographically secure and wasi random_get is expected to provide cryptographically secure random bytes. If a WASM module relies on random_get for generating keys, tokens, or nonces, this could weaken security. This is a real quality/security issue in the original @wasmer/wasi-compatible code.

### [medium] Path Traversal Risk in resolvePath

Finding ID: `NPS-F61835C652CF`

File: `lib/mjs/wasi/preview1.mjs`

resolvePathSync/resolvePathAsync and many path_* syscalls use resolve(fileDescriptor.realPath, path) without verifying that the resulting path stays within the preopened directory. A WASM guest could supply '../../etc/passwd' style paths to escape the sandbox if the resolve function does not enforce containment. This is a capability-bypass concern typical of WASI implementations and should be verified against resolve() in path.mjs.

### [low] Host OS Detection

Finding ID: `NPS-AEF37515FBC4`

File: `lib/cjs/wasi/path.js:21`

The code checks `process.platform === 'win32'` to route path resolution to a Windows-specific implementation. This is benign platform detection necessary for correct path handling and does not involve any suspicious activity.

### [low] Environment Variable Read

Finding ID: `NPS-A156C20CADAA`

File: `lib/cjs/wasi/path.js:68`

The code reads the `process.env` object to look up the per-drive current working directory (`=X:` environment variable convention) on Windows. This is standard behavior used by Node.js's built-in `path.win32.resolve` to support Windows drive-specific working directories, and the values read are only used locally for path resolution, not exfiltrated.

### [low] File System Operations Outside Package Scope

Finding ID: `NPS-C8BAFCF34356`

File: `lib/cjs/wasi/preview1.js`

This is the core function of a WASI implementation: it provides file system access to WebAssembly guests. By design, it manipulates files and directories via Node's `fs` module. While expected for this library, any vulnerability in path resolution or rights checking (see above) would allow arbitrary file system manipulation. The code does implement a rights-based capability system, which is a positive security control.

### [low] Windows Open Flags Translation Bypass

Finding ID: `NPS-9AC762A0B967`

File: `lib/cjs/wasi/preview1.js:15`

`_toWinOpenFlags` translates Linux flag bits to Windows libuv flags, but starts with `let r = f & 3;` which only preserves the lowest two bits (access mode). All other flags not explicitly handled (e.g., `O_NONBLOCK`, `O_SYNC`, `O_DIRECTORY`) are silently dropped on Windows. While this is primarily a correctness issue, it could lead to unexpected permission bypasses (e.g., `O_DIRECTORY` not being enforced at the OS level on Windows).

### [low] Worker Thread Interaction

Finding ID: `NPS-57DBCF7B3B84`

File: `lib/cjs/wasi/util.js:82`

The code conditionally loads `worker_threads` and defines a `postMessage` implementation that sends data to `parentPort`. This is expected behavior for a WASI utility library but could be abused for data exfiltration if the data originates from sensitive sources.

### [low] Environment variable access

Finding ID: `NPS-F88D66A6D658`

File: `lib/mjs/wasi/path.mjs`

Reads process.env for per-drive cwd lookups using the '=X:' convention. This is legitimate Windows path resolution behavior for determining current working directory per drive, not credential harvesting.

### [low] Data exposure via /proc-like env access

Finding ID: `NPS-9ABE209D4B62`

File: `lib/mjs/wasi/preview1.mjs`

environ_get and environ_sizes_get expose all process.env values (env array passed into constructor) to the WASM guest. If the host passes full process.env, secrets such as tokens, API keys, and AWS credentials could be leaked into the WASI sandbox. This is by design in WASI but a misconfiguration risk.

### [low] Conditional debug logging of env

Finding ID: `NPS-963BA0B6F5E0`

File: `lib/mjs/wasi/preview1.mjs`

NODE_DEBUG_NATIVE env var is read and, if it includes 'wasi', arguments to syscalls are logged via console.debug. Not malicious, but reading process.env at module scope could allow an attacker who controls the process environment to enable verbose logging of syscall arguments (paths, fds). Low impact.

### [low] Computed property definition

Finding ID: `NPS-01C0A52FD59F`

File: `lib/mjs/wasi/util.mjs:58`

wrapInstanceExports uses Object.defineProperty on arbitrary export names from the provided exports object. No external input is involved here, but it is a pattern worth noting for WASI module wrapping.

### [low] Dynamic module loading

Finding ID: `NPS-A2F4914A01B0`

File: `lib/mjs/wasi/util.mjs:67`

The code attempts to obtain a native require function via __webpack_public_path__ and __non_webpack_require__, then uses it to load the 'worker_threads' module. While the target module is hardcoded, this pattern bypasses webpack bundling and can be used to load arbitrary modules in some environments.

### [low] Potential worker thread interaction

Finding ID: `NPS-C2A09C64A65F`

File: `lib/mjs/wasi/util.mjs:87`

The module conditionally spawns or interacts with worker_threads, including reading isMainThread and using parentPort.postMessage to send data to the main thread. This is legitimate for WASI threading support but constitutes inter-thread communication that could be abused if the package is compromised.

## Files reviewed

- `lib/cjs/wasi/preview1.js` (medium): This is a legitimate WASI Preview1 implementation for Node.js/WebAssembly, but it contains a weak random fallback and relies entirely on a custom path resolver—a potential sandbox escape vector if that resolver is flawed.
- `lib/cjs/wasi/util.js` (medium): The file contains dynamic module requiring logic that could bypass bundler analysis, but no outright malicious behavior like data exfiltration, credential harvesting, or backdoor installation was detected.
- `lib/mjs/wasi/preview1.mjs` (medium): This is a legitimate WASI preview1 shim (similar to @wasmer/wasi / @tybys/wasm-util) with no evidence of exfiltration, backdoors, or obfuscation, but it contains a non-cryptographic Math.random fallback in random_get and potential path-sandbox escape concerns that require review of the imported resolve() implementation.
- `lib/mjs/wasi/util.mjs` (medium): The file contains only utility validation functions and environment detection; no clearly malicious behavior, but it uses non-standard dynamic require access and worker_threads communication that warrant low-severity scrutiny.
- `lib/cjs/asyncify.js` (safe): No malicious patterns detected; the code is a legitimate WebAssembly Asyncify utility with no data exfiltration, credential harvesting, obfuscation, or process execution.
- `lib/cjs/index.js` (safe): No malicious patterns detected; the file only re-exports local modules and contains no dynamic execution, network, filesystem, or process activity.
- `lib/cjs/jspi.js` (safe): No malicious patterns detected; the code only provides WebAssembly function wrapping utilities for JSPI without any network, filesystem, process, or dynamic code execution behavior.
- `lib/cjs/load.js` (safe): The code is a WebAssembly loader utility with no malicious patterns; all network and filesystem-like operations are limited to fetching a developer-provided WASM URL.
- `lib/cjs/memory.js` (safe): No malicious patterns detected
- `lib/cjs/wasi/error.js` (safe): Cleared by Jev triage; no further analysis needed
- `lib/cjs/wasi/fd.js` (safe): No malicious patterns detected; the file implements WASI file descriptor table logic with no network, credential, obfuscation, or process-spawning behavior.
- `lib/cjs/wasi/fs.js` (safe): No malicious patterns detected
- `lib/cjs/wasi/index.js` (safe): No malicious patterns detected; the code is a legitimate WASI implementation with standard option validation and instance management.
- `lib/cjs/wasi/path.js` (safe): The file implements POSIX/Windows path resolution utilities (resolve, relative) with standard Node.js-compatible logic; it reads process.env only to look up Windows per-drive cwd conventions and contains no malicious patterns such as network calls, file system access, code execution, or credential harvesting.
- `lib/cjs/wasi/rights.js` (safe): No malicious patterns detected; this file defines WASI filesystem rights constants and a pure getRights() function with no network, process, filesystem, or dynamic code execution behavior.
- `lib/cjs/wasi/types.js` (safe): No malicious patterns detected
- `lib/cjs/webassembly.js` (safe): No malicious patterns detected; the code only provides a WebAssembly environment abstraction with a support check.
- `lib/mjs/asyncify.mjs` (safe): This is a legitimate WebAssembly Asyncify helper module with no malicious patterns such as data exfiltration, credential harvesting, dynamic code execution, or suspicious network/file system activity.
- `lib/mjs/index.mjs` (safe): Cleared by Jev triage; no further analysis needed
- `lib/mjs/jspi.mjs` (safe): No malicious patterns detected; the code only wraps WebAssembly functions without network, filesystem, or process access.
- `lib/mjs/load.mjs` (safe): No malicious patterns detected; the module performs standard WebAssembly instantiation and loading via fetch without any exfiltration, obfuscation, or system manipulation.
- `lib/mjs/memory.mjs` (safe): No malicious patterns detected; the code is a straightforward WebAssembly Memory wrapper with no exfiltration, credential harvesting, obfuscation, or other security concerns.
- `lib/mjs/wasi/error.mjs` (safe): Cleared by Jev triage; no further analysis needed
- `lib/mjs/wasi/fd.mjs` (safe): No malicious patterns detected; this file implements WASI file descriptor tables and standard output buffering without external network, process, or credential access.
- `lib/mjs/wasi/fs.mjs` (safe): Cleared by Jev triage; no further analysis needed
- `lib/mjs/wasi/index.mjs` (safe): No malicious patterns detected; the code is a legitimate Node.js WASI implementation with standard validation and no exfiltration, obfuscation, or dynamic code execution.
- `lib/mjs/wasi/path.mjs` (safe): This is a clean implementation of Node.js-compatible path resolution (resolveWin32, resolve, relative) with standard filesystem path logic and no malicious patterns detected.
- `lib/mjs/wasi/rights.mjs` (safe): Cleared by Jev triage; no further analysis needed
- `lib/mjs/wasi/types.mjs` (safe): No malicious patterns detected
- `lib/mjs/webassembly.mjs` (safe): No malicious patterns detected

## Version ranges

None of the 2 scanned versions of @tybys/wasm-util are flagged high or critical. The latest scanned version, 0.10.4, is medium risk. Only versions we have scanned are listed; unscanned versions between them are not covered.

- 0.10.4 (`0.10.4`): medium (Dynamic Module Require +1 more)
- 0.10.3 (`0.10.3`): not scanned
- 0.10.2 (`0.10.2`): medium (Path Traversal / Sandbox Escape Risk +4 more)
- 0.9.0 – 0.10.1 (`>=0.9.0 <=0.10.1`): not scanned

## Scanned versions

- [0.10.4](https://security.togoder.click/npm/@tybys/wasm-util@0.10.4): medium, 2026-10-06T14:13:00.000Z
- [0.10.2](https://security.togoder.click/npm/@tybys/wasm-util@0.10.2): medium, 2026-10-06T14:12:29.000Z

AI analysis is guidance, not a guarantee. Methodology: https://security.togoder.click/methodology
