# @scalar/json-magic@0.15.2 security report (npm)

- Verdict: **Needs review** (risk level: medium)
- Scanned: 2026-10-06T14:12:01.000Z
- Files reviewed: 41
- Findings: 8 medium, 10 low severity findings
- Report: https://security.togoder.click/npm/@scalar/json-magic
- Source: Togoder Security (https://security.togoder.click), AI source-code review

## Summary

Togoder Security scanned the npm package @scalar/json-magic@0.15.2 on Oct 6, 2026. An AI review of 41 source files produced 8 medium, 10 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

### [medium] Network requests via external plugins

Finding ID: `NPS-DF094247AA62`

File: `dist/bundle/bundle.js`

The bundler resolves external $ref URLs and file paths using loader plugins. This can cause network requests or file reads to arbitrary URLs/paths specified in the input OpenAPI document. If a malicious or untrusted spec is processed, this could be used for SSRF or local file disclosure, depending on the plugins configured by the caller.

### [medium] Potential SSRF / arbitrary network request

Finding ID: `NPS-C7C5530788DE`

File: `dist/bundle/plugins/fetch-urls/browser.js:21`

The plugin fetches arbitrary URLs provided as input. While it uses `isHttpUrl` for validation and an optional limiter, there is no allowlist or domain restriction. An attacker who can influence the input URL could make requests to internal services or arbitrary hosts. This is a design risk rather than overtly malicious behavior.

### [medium] Network requests with customizable headers and fetch

Finding ID: `NPS-8D19B7BA3D75`

File: `dist/bundle/plugins/fetch-urls/index.js:47`

The function fetches remote URLs and allows custom headers and a custom fetch function via config. This could be abused to send requests to arbitrary internal or external endpoints, potentially leaking sensitive headers. The code attempts to mitigate private network access when blockPrivateNetworks is set, but the custom fetch bypass is explicitly blocked only under that condition.

### [medium] Potential SSRF via configurable URL and headers

Finding ID: `NPS-B29D4D625B58`

File: `dist/bundle/plugins/fetch-urls/index.js:88`

The plugin validates URLs using isHttpUrl, which may not sufficiently restrict internal network addresses. Combined with configurable headers, this could be used for server-side request forgery (SSRF) to internal services, especially in server-side contexts.

### [medium] Potential YAML deserialization vulnerability

Finding ID: `NPS-FC891ABB3C81`

File: `dist/bundle/plugins/parse-yaml/index.js:22`

The code uses YAML.parse with `merge: true` and an unusually high `maxAliasCount` of 10000. While maxAliasCount is set to prevent billion laughs/alias expansion DoS, the high limit still allows significant resource consumption. More importantly, YAML parsing of untrusted input can lead to prototype pollution or object injection depending on the parser implementation, though the 'yaml' library is generally considered safe compared to js-yaml. The `merge: true` option enables YAML merge keys which, if combined with untrusted input, could allow an attacker to override object properties in unexpected ways.

### [medium] Network requests / external resource fetching

Finding ID: `NPS-2650F7D6BC53`

File: `dist/dereference/dereference.js:40`

The default plugin `fetchUrls()` is used when no custom plugins are provided. This causes the library to make outbound network requests to arbitrary URLs referenced via $ref pointers in the input document. If untrusted input is processed, this can lead to SSRF or exfiltration of data to attacker-controlled hosts, and can be abused to fetch internal resources.

### [medium] yaml-alias-expansion

Finding ID: `NPS-88536BFBAE11`

File: `dist/helpers/normalize.js:27`

The code uses the `yaml` library's `parse` function with `maxAliasCount: 10000`, which is a very high limit for YAML alias expansion. This can lead to a denial-of-service (DoS) vulnerability (Billion Laughs attack / entity expansion) when parsing untrusted YAML input, as the high alias count allows excessive memory and CPU consumption.

### [medium] Prototype pollution via __proto__ handling

Finding ID: `NPS-FBA24213446E`

File: `dist/magic-proxy/proxy.js:189`

In the 'set' trap, when a $ref-value is being set, if the resolved key is '__proto__', the code explicitly uses Object.defineProperty to set the property on the parent object. While this is intended to safely handle the '__proto__' key, the presence of explicit __proto__ handling in a proxy that wraps arbitrary user-provided JSON data is a security concern. An attacker-controlled JSON Reference could potentially be crafted to cause prototype pollution if the parent object is not properly guarded. However, in this specific implementation, the use of Object.defineProperty with configurable/writable/enumerable set to true mitigates the typical prototype pollution vector, but it still represents a risky pattern that warrants review.

### [low] Dynamic plugin execution

Finding ID: `NPS-E3BE30BF691C`

File: `dist/bundle/bundle.js`

The code dynamically discovers and executes plugin functions (validate/exec, resolveDocument, lifecycle hooks) from the config. If an attacker can control the plugin list, arbitrary code can be executed. However, this is by design for a plugin-based bundler and requires attacker control of config.

### [low] Custom headers sent to arbitrary domains

Finding ID: `NPS-2F742A668090`

File: `dist/bundle/plugins/fetch-urls/browser.js:23`

Configurable headers are attached to outgoing requests based on host matching. If a misconfigured or malicious config lists sensitive headers for broad domains, credentials could leak to unintended hosts.

### [low] Dynamic function invocation from config

Finding ID: `NPS-CA8C56DE5E59`

File: `dist/bundle/plugins/fetch-urls/browser.js:24`

The code allows the caller-supplied config object to override the fetch implementation (`config?.fetch ?? fetch`). This is a form of dependency injection that could be abused if config is attacker-controlled, enabling arbitrary request logic.

### [low] Top-level code execution on import

Finding ID: `NPS-37C704E02D26`

File: `dist/bundle/plugins/fetch-urls/index.js`

The module does not appear to execute any code at import time beyond defining functions and importing dependencies. The dynamic import is inside an async function, so it only runs when called.

### [low] Dynamic import with external input

Finding ID: `NPS-3CD4245F572F`

File: `dist/bundle/plugins/fetch-urls/index.js:50`

The code uses dynamic import('./fetch-public-url.js') based on config values. While the path itself is static, dynamic imports can be a vector for code injection if the module path were to become user-controlled. Here the path is hardcoded, so risk is low, but still a pattern to monitor.

### [low] Dynamic behavior via user-supplied plugins

Finding ID: `NPS-1C58B2AB3982`

File: `dist/dereference/dereference.js:39`

The function accepts arbitrary `options.plugins` and passes them to `bundle()`. Custom loader/resolver plugins can execute arbitrary code paths (e.g. resolving `workspace:` schemes to file contents), which, if the library is used with untrusted configuration, could allow local file reads or other unexpected behavior. This is by design but warrants caution.

### [low] Prototype pollution defense

Finding ID: `NPS-AD21F2A1C1DE`

File: `dist/diff/utils.js`

The code explicitly imports and uses `isPollutionKey` to skip prototype-polluting keys (`__proto__`, `constructor`, `prototype`) in both `isKeyCollisions` and `mergeObjects`, actively preventing prototype pollution. This is a security-positive pattern.

### [low] Minor logic bug

Finding ID: `NPS-D0843CA24D95`

File: `dist/diff/utils.js`

In `isArrayEqual`, the loop condition is `i <= a.length`, which iterates one element past the end of the array (accessing `a[a.length]` and `b[b.length]`). Both sides will be `undefined` and thus compare equal, so the result is not incorrect, but the off-by-one condition is a latent bug worth flagging. No security impact.

### [low] yaml-merge-key

Finding ID: `NPS-22D51BABFCE6`

File: `dist/helpers/normalize.js:28`

The YAML parser is configured with `merge: true`, enabling YAML merge keys. While not inherently malicious, this feature can be abused in prototype pollution attacks if the parsed output is later merged into plain JavaScript objects without proper sanitization.

### [low] Console output with user-controlled data

Finding ID: `NPS-B154DAC4548F`

File: `dist/magic-proxy/proxy.js:185`

The code uses console.warn with a message that includes the user-controlled 'ref' variable when attempting to set a $ref-value for an invalid reference. While not a direct security vulnerability, logging user-controlled data to the console can lead to log injection or information disclosure in certain environments.

## Files reviewed

- `dist/bundle/bundle.js` (medium): This is a legitimate OpenAPI bundler library with expected network/file resolution behavior via plugins; no clear malicious patterns like exfiltration, credential harvesting, eval, or backdoors were found.
- `dist/bundle/plugins/fetch-urls/browser.js` (medium): The code performs expected remote URL fetching for an OpenAPI/loader plugin without evident exfiltration, credential harvesting, obfuscation, or shell execution, but its unconstrained URL fetching and configurable fetch/headers introduce SSRF and header-leakage risks.
- `dist/bundle/plugins/fetch-urls/index.js` (medium): The code is primarily a URL fetching utility with some security-sensitive patterns such as dynamic imports and configurable network requests, but no clear malicious intent is evident.
- `dist/bundle/plugins/parse-yaml/index.js` (medium): No direct malicious patterns (exfiltration, credential harvesting, code execution, etc.) were found, but the YAML parsing configuration with merge enabled and a high alias count could pose a deserialization risk if fed untrusted input.
- `dist/dereference/dereference.js` (medium): No overtly malicious code (no exfiltration, credential harvesting, obfuscation, shells, or install-time hooks) is present, but the default behavior of fetching arbitrary $ref URLs and accepting arbitrary plugins introduces SSRF/local-file-read risk when processing untrusted input.
- `dist/helpers/normalize.js` (medium): No malicious patterns found, but the YAML parsing configuration uses a very high alias count limit and enables merge keys, which could introduce DoS or prototype pollution risks with untrusted input.
- `dist/magic-proxy/proxy.js` (medium): The code implements a proxy for resolving JSON References and contains explicit __proto__ handling that could be a prototype pollution risk, though mitigated, and logs user-controlled data to the console.
- `dist/bundle/document-references.js` (safe): No malicious patterns detected
- `dist/bundle/index.js` (safe): No malicious patterns detected
- `dist/bundle/plugins/browser.js` (safe): No malicious patterns detected
- `dist/bundle/plugins/fetch-urls/fetch-public-url.js` (safe): The code implements a secure HTTP fetcher with DNS pinning to prevent SSRF attacks and contains no malicious patterns.
- `dist/bundle/plugins/fetch-urls/is-blocked-host.js` (safe): This module implements SSRF protection by blocking private, loopback, link-local, and IPv6 transition address ranges; no malicious patterns, exfiltration, credential harvesting, obfuscation, or code execution were detected.
- `dist/bundle/plugins/node.js` (safe): No malicious patterns detected
- `dist/bundle/plugins/parse-json/index.js` (safe): Cleared by Jev triage; no further analysis needed
- `dist/bundle/plugins/read-files/index.js` (safe): No malicious patterns detected; the code implements a path-confined file reader with symlink dereferencing and no exfiltration, credential access, or dynamic execution.
- `dist/bundle/value-generator.js` (safe): No malicious patterns detected; the code is a straightforward hash-based unique value generator with no network, filesystem, or process access.
- `dist/dereference/index.js` (safe): Cleared by Jev triage; no further analysis needed
- `dist/diff/apply.js` (safe): The code implements a JSON-diff application utility with explicit prototype-pollution guards and no network, filesystem, process, or dynamic-execution behavior.
- `dist/diff/diff.js` (safe): No malicious patterns detected; the code is a defensive object diff utility that explicitly guards against prototype pollution via isPollutionKey filtering.
- `dist/diff/index.js` (safe): Cleared by Jev triage; no further analysis needed
- `dist/diff/merge.js` (safe): No malicious patterns detected; the code is a benign diff-merge utility with no network, file system, process, or dynamic execution concerns.
- `dist/diff/trie.js` (safe): No malicious patterns detected; the code implements a trie data structure with proper prototype pollution protection using null-prototype objects.
- `dist/diff/utils.js` (safe): No malicious patterns detected; the module is a pure in-memory object diff/merge utility that explicitly guards against prototype pollution, with no network, filesystem, process, or dynamic-code behavior.
- `dist/helpers/convert-to-local-ref.js` (safe): Cleared by Jev triage; no further analysis needed
- `dist/helpers/escape-json-pointer.js` (safe): Cleared by Jev triage; no further analysis needed
- `dist/helpers/get-schemas.js` (safe): Cleared by Jev triage; no further analysis needed
- `dist/helpers/get-segments-from-path.js` (safe): Cleared by Jev triage; no further analysis needed
- `dist/helpers/get-value-by-path.js` (safe): Cleared by Jev triage; no further analysis needed
- `dist/helpers/is-file-path.js` (safe): Cleared by Jev triage; no further analysis needed
- `dist/helpers/is-http-url.js` (safe): Cleared by Jev triage; no further analysis needed
- `dist/helpers/is-json-object.js` (safe): Cleared by Jev triage; no further analysis needed
- `dist/helpers/is-yaml.js` (safe): Cleared by Jev triage; no further analysis needed
- `dist/helpers/json-path-utils.js` (safe): No malicious patterns detected
- `dist/helpers/resolve-reference-path.js` (safe): No malicious patterns detected; the code is a straightforward reference path resolver using standard URL and path utilities without network, filesystem, or process manipulation.
- `dist/helpers/set-value-at-path.js` (safe): No malicious patterns detected; the code is a utility function for safely setting values at object paths with prototype pollution prevention.
- `dist/helpers/to-relative-path.js` (safe): The code is a pure path/URL normalization utility with no network, filesystem, process, or eval activity.
- `dist/helpers/unescape-json-pointer.js` (safe): Cleared by Jev triage; no further analysis needed
- `dist/join/index.js` (safe): Cleared by Jev triage; no further analysis needed
- `dist/join/join.js` (safe): No malicious patterns detected; the code is a pure in-memory JSON merge utility with safe property handling and no external I/O or execution.
- `dist/magic-proxy/index.js` (safe): Cleared by Jev triage; no further analysis needed
- `dist/types.js` (safe): Cleared by Jev triage; no further analysis needed

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