CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-71438

CVE-2026-71438: Prototype Pollution in Mermaid Configuration APIs

Alon Barad
Alon Barad
Software Engineer

Aug 6, 2026·7 min read·6 visits

Executive Summary (TL;DR)

A prototype pollution vulnerability in Mermaid's deep-merge utility allowed global prototype corruption when processing untrusted configuration objects, resolved in patched versions via strict Object.hasOwn and Object.defineProperty checks.

Prior to versions 10.9.8 and 11.16.1, Mermaid is vulnerable to prototype pollution via its deep-merge utility function assignWithDepth. This helper is invoked by public configuration-setting interfaces, specifically mermaid.initialize, mermaidAPI.setConfig, and mermaidAPI.updateSiteConfig. Because assignWithDepth recursively merges developer-provided properties into Mermaid's internal configuration state without proper sanitization, an attacker who can control or influence the configuration payload can corrupt the global Object.prototype. This vulnerability can lead to security bypasses, cross-site scripting (XSS), or execution flow modifications in applications using vulnerable Mermaid integrations.

Vulnerability Overview

Mermaid is a widely deployed client-side and server-side JavaScript library designed to parse Markdown-inspired text and generate structured charts, flowcharts, and sequence diagrams. In modern single-page applications, content-management portals, and documentation frameworks, Mermaid is heavily integrated as the rendering engine for visualization payloads. The library exposes public APIs allowing developers to specify layout preferences, security controls, and visual styling configurations globally or dynamically.\n\nThe attack surface of interest involves Mermaid's configuration-setting interfaces, specifically the initialize, setConfig, and updateSiteConfig APIs. When a host application initializes or updates its diagramming parameters, these APIs ingest data structured as nested JSON properties. To merge the incoming values into the internal configuration object without overriding adjacent properties, the library relies on an internal deep-merge utility named assignWithDepth.\n\nThe vulnerability, designated CVE-2026-71438 and mapped under CWE-1321, arises because assignWithDepth recursively merges properties without checking for special keys that access the global object prototype. Consequently, if a downstream application accepts untrusted configurations from external inputs and directly passes them to the initialization endpoints, an attacker can supply malicious keys to overwrite prototype behaviors. This introduces a vector for prototype pollution, which can be leveraged to disable security sandboxes or alter core application configurations.

Root Cause Analysis

The vulnerability resides in packages/mermaid/src/assignWithDepth.ts within the recursive helper utility assignWithDepth. This function takes a destination object and a source object, then recursively copies key-value pairs from the source to the destination. Because the loop was designed to handle arbitrarily nested objects, it evaluates each key without validating whether the key string is a forbidden descriptor, such as proto or constructor.\n\nWhen processing an untrusted object, the engine iterates over its properties using Object.keys(src). If the source object contains a nested key named proto, the function evaluates the expression (dst[key] === undefined || typeof dst[key] === 'object'). Since proto naturally exists on the prototype chain of any standard JavaScript object, querying dst['proto'] returns the base Object.prototype. This causes the typeof check to evaluate to 'object' instead of resolving to undefined.\n\nFollowing this lookup, the algorithm attempts to merge properties of the nested object into the base prototype by calling assignWithDepth recursively with the prototype itself as the new destination. Because JavaScript objects inherit from this prototype, any modifications written to it pollute the global context. Subsequent lookups for these key-value pairs on completely unrelated objects will yield the polluted values, altering global state across the entire execution sandbox.

Code Analysis

The core issue is apparent when comparing the vulnerable assignment logic to the patched version. In the vulnerable code path, property evaluation is performed directly using bracket notation accessor checks without validating the inheritance structure. The following snippet illustrates the original implementation of the recursive loop:\n\ntypescript\n// VULNERABLE IMPLEMENTATION\nObject.keys(src).forEach((key) => {\n if (\n typeof src[key] === 'object' &&\n src[key] !== null &&\n (dst[key] === undefined || typeof dst[key] === 'object')\n ) {\n if (dst[key] === undefined) {\n dst[key] = Array.isArray(src[key]) ? [] : {};\n }\n dst[key] = assignWithDepth(dst[key], src[key], { depth: depth - 1, clobber });\n } else if (clobber || (typeof dst[key] !== 'object' && typeof src[key] !== 'object')) {\n dst[key] = src[key];\n }\n});\n\n\nThis implementation is unsafe because bracket accessors traverse the inheritance chain. The patch resolves this behavior by replacing simple key checks with Object.hasOwn() and Object.defineProperty(). Rather than assigning properties directly with bracket notation, the patched algorithm ensures that any property modified must be an own property of the target object:\n\ntypescript\n// PATCHED IMPLEMENTATION\nObject.entries(src).forEach(([key, srcValue]) => {\n if (typeof srcValue === 'object') {\n if (srcValue === null) {\n return;\n }\n if (!Object.hasOwn(dst, key)) {\n Object.defineProperty(dst, key, {\n value: undefined,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n }\n if (dstWithKeys[key] === undefined) {\n dstWithKeys[key] = Array.isArray(srcValue) ? [] : {};\n }\n if (typeof dstWithKeys[key] === 'object') {\n dstWithKeys[key] = assignWithDepth(dstWithKeys[key], srcValue, { depth: depth - 1 });\n }\n } else if (typeof dstWithKeys[key] !== 'object') {\n if (Object.hasOwn(dst, key)) {\n dstWithKeys[key] = srcValue;\n } else {\n Object.defineProperty(dst, key, {\n value: srcValue,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n }\n }\n});\n\n\nBy leveraging Object.hasOwn(dst, key), the utility checks whether dst contains the property directly. If dst does not own the key, Object.defineProperty is used to declare an own property on dst with a value of undefined. This physically overrides the prototype lookup mechanism, isolating any subsequent writes to this local property and preventing global leakage.

Exploitation Methodology

Exploiting CVE-2026-71438 requires a specific application architecture. The hosting application must ingest configuration objects directly from a user-controlled, unsanitized source—such as a JSON payload delivered via a REST API, query parameters, or form fields. Once received, the application must pass this configuration object directly into mermaid.initialize(), mermaidAPI.setConfig(), or mermaidAPI.updateSiteConfig().\n\nAn attacker can craft a payload containing a proto property containing a nested securityLevel assignment. The structured JSON attack vector is shown below:\n\njson\n{\n \"__proto__\": {\n \"securityLevel\": \"loose\"\n }\n}\n\n\nWhen the host application passes this object to the vulnerable Mermaid configuration sink, assignWithDepth traverses the proto key. It verifies that typeof dst['proto'] is 'object', then recursively processes the nested object. Consequently, the value of Object.prototype.securityLevel is set to 'loose'.\n\nOnce global prototype pollution is achieved, the security sandbox configurations of all subsequent diagram renderers are compromised. Because Mermaid defaults to checking securityLevel during parser execution, any subsequently generated diagram will execute under the polluted loose security context. This disables default script filtering and sandbox protection, allowing the attacker to trigger client-side Cross-Site Scripting (XSS) or arbitrary HTML execution through standard diagram syntaxes. It is important to note that configuration declarations embedded inside diagram syntax itself, such as frontmatter blocks or directive comments, are processed via isolated sanitization pipelines and are not vulnerable.

Impact Assessment

The impact of CVE-2026-71438 is classified as Medium, receiving a CVSS v4.0 score of 2.4. This low direct score is due to the severe prerequisites required for exploitation. An attacker must find an application that directly exposes the programmatic configuration interface of the Mermaid library to unvalidated user-controlled JSON data, which is an uncommon design pattern in standard integrations.\n\nIn scenarios where this configuration capability is exposed, the downstream impact is significant. Corrupting the Object.prototype globally can lead to widespread execution flow bypasses, modification of default rendering properties, or unexpected denial-of-service conditions in the host application. The primary hazard is the disabling of the securityLevel sandbox, which transitions the application from a safe diagram renderer to an unvalidated scripting environment.\n\nFurthermore, because JavaScript prototype pollution affects all objects running in the same thread, the state corruption can bleed into unrelated application components. If the application runs in a Node.js context (such as a server-side diagram generator), the pollution of Object.prototype can manipulate routing mechanisms, templating engines, or data-validation frameworks, introducing secondary execution vectors across the entire platform.

Remediation and Mitigation

Remediation of CVE-2026-71438 requires upgrading the Mermaid library to safe versions. Applications using the v11 release line must upgrade to version 11.16.1 or later, while projects locked to the v10 release line must upgrade to version 10.9.8 or later. These versions contain the hardened assignWithDepth implementation that physically prevents prototype modification via Object.hasOwn and Object.defineProperty.\n\nIf immediate dependency upgrades are not possible, host applications must implement input-validation controls at the ingestion boundary. This involves sanitizing incoming JSON payloads by stripping or blocking keys containing proto, constructor, or prototype properties before passing the object to Mermaid's initialization routines. An example validation filter is illustrated below:\n\njavascript\nfunction sanitizeConfig(config) {\n const serialized = JSON.stringify(config);\n if (serialized.includes('__proto__') || serialized.includes('constructor')) {\n throw new Error('Malicious configuration payload detected');\n }\n return config;\n}\n\n\nAdditionally, developers should note that mermaidAPI.setConfig has been formally deprecated. The configuration management has been refactored to compile rendering parameters dynamically during execution, ensuring that state is not persistently stored on vulnerable global variables. Adopting Content Security Policy (CSP) headers that restrict script execution to trusted domains further mitigates any successful downstream XSS attempts.

Fix Analysis (2)

Technical Appendix

CVSS Score
2.4/ 10
CVSS:4.0/AV:L/AC:L/AT:P/PR:H/UI:A/VC:N/VI:L/VA:L/SC:H/SI:H/SA:H

Affected Systems

Mermaid JS LibraryApplications dynamically initializing Mermaid with user-controlled configuration objects

Affected Versions Detail

Product
Affected Versions
Fixed Version
mermaid
mermaid-js
< 10.9.810.9.8
mermaid
mermaid-js
>= 11.0.0-alpha.1, < 11.16.111.16.1
AttributeDetail
CWE IDCWE-1321
Attack VectorLocal / Indirect via host configuration sink
CVSS Score2.4 (Low)
EPSS Score0.00043
ImpactSecurity control bypass, global property modification
Exploit StatusProof-of-Concept
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1059Command and Scripting Interpreter
Execution
CWE-1321
Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')

The software modifies the attributes of an object prototype in a manner that can allow an attacker to execute arbitrary code, bypass security controls, or cause a denial of service.

Known Exploits & Detection

GitHub Security AdvisoryAdvisory containing theoretical exploitation guidelines and reproduction paths.

Vulnerability Timeline

Core fix and unit tests committed to v11 development branch.
2026-08-04
Core patch backported to v10 branch.
2026-08-04
Vulnerability catalogued by GitHub Security Advisories and assigned CVE-2026-71438.
2026-08-06
Official releases v10.9.8 and v11.16.1 published.
2026-08-06

References & Sources

  • [1]GitHub Security Advisory GHSA-c4c3-pg64-4m4v
  • [2]Mermaid Pull Request 8022
  • [3]Mermaid Fix Commit (v11.x)
  • [4]Mermaid Fix Commit (v10.x)
  • [5]Mermaid Release Tag 11.16.1
  • [6]Mermaid Release Tag 10.9.8
  • [7]CVE.org Authority Record

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 1 hour ago•CVE-2026-71850
4.8

CVE-2026-71850: Server-Side Rendering Data Exposure in Hono JSX Memoization

A session data exposure vulnerability in the Hono web application framework (hono/jsx module) allows consecutive users to receive cached HTML outputs containing private data. When JSX components wrapped in `memo()` are rendered on the server, the caching mechanism utilizes a module-level closure that persists across independent HTTP requests. When subsequent requests occur with matching props, the components are not re-evaluated, and cached HTML is served. If these components read request-scoped or session-specific data via ambient APIs, the data of the first user is exposed to subsequent users.

Amit Schendel
Amit Schendel
1 views•6 min read
•about 2 hours ago•CVE-2026-71851
9.0

CVE-2026-71851: Use of Cryptographically Weak PRNG in crypto-js (Ill Bloom)

A severe, twelve-year-old cryptographic weakness in crypto-js (versions < 4.0.0) generated pseudorandom numbers using a custom Multiply-With-Carry (MWC) algorithm seeded from the non-secure Math.random(). This reduces 128-bit and 256-bit key spaces to just 2^39 and 2^47 possibilities, allowing offline brute-force attacks.

Alon Barad
Alon Barad
2 views•7 min read
•about 3 hours ago•CVE-2026-71870
4.8

CVE-2026-71870: Uncontrolled Resource Consumption (DoS) in pypdf ToUnicode CMap Parsing

An uncontrolled resource consumption vulnerability (CWE-400) exists in pypdf prior to version 6.15.0. When extracting text from a specially crafted PDF document, the parser fails to restrict token lengths within /ToUnicode CMap streams, causing unbounded memory allocation and process termination via Out-of-Memory (OOM) crashes.

Amit Schendel
Amit Schendel
5 views•7 min read
•about 4 hours ago•CVE-2026-71852
4.8

CVE-2026-71852: Denial of Service via Excessive Iteration and Memory Exhaustion in pypdf CID Font Parsing

A Denial of Service (DoS) vulnerability exists in pypdf prior to version 6.15.0. When parsing maliciously crafted PDF files containing excessively large CID font width ranges, the library suffers from CPU starvation and memory exhaustion due to unconstrained loop expansion.

Amit Schendel
Amit Schendel
6 views•7 min read
•about 5 hours ago•CVE-2026-56818
6.5

CVE-2026-56818: Denial of Service via Memory Pinning in Netty Redis Array Aggregator

A vulnerability in Netty's Redis codec allows remote unauthenticated attackers to cause a memory-pinning Denial of Service (DoS) due to the failure to release partial aggregate state when specific error conditions occur in RedisArrayAggregator. When processing Redis Serialization Protocol (RESP) messages, the aggregator fails to clear internal queues and release retained direct byte buffers on exception paths triggered by exceeded maxElements or invalid length properties. If the pipeline does not explicitly tear down the connection upon detecting a decoder error, subsequent elements continue utilizing the stale context, allowing memory blocks to remain indefinitely pinned.

Amit Schendel
Amit Schendel
6 views•5 min read
•about 6 hours ago•CVE-2026-54164
6.5

CVE-2026-54164: Missing IRI Type Validation in API Platform Core Enables Resource Type Confusion

CVE-2026-54164 is a class/type confusion vulnerability (CWE-843) in API Platform Core. When processing relationships via Internationalized Resource Identifiers (IRIs) in write requests, the framework's normalizer fails to verify if the resolved resource matches the expected type. For PHP applications utilizing untyped properties, the mismatched object is silently assigned, breaking domain logic and data integrity.

Alon Barad
Alon Barad
4 views•6 min read