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



GHSA-PHWJ-RPRQ-35PP

GHSA-PHWJ-RPRQ-35PP: Use-After-Free Vulnerability in Nokogiri XML Attribute Value Modification

Amit Schendel
Amit Schendel
Senior Security Researcher

Jun 19, 2026·6 min read·29 visits

Executive Summary (TL;DR)

A use-after-free vulnerability in the Nokogiri gem's CRuby extension allows remote attackers to trigger process crashes or memory corruption when updating XML attribute values.

A use-after-free (UAF) vulnerability exists in the CRuby native extension of the Nokogiri gem when updating XML attribute values. If child nodes of an XML attribute are wrapped by Ruby objects prior to setting the attribute's value, the underlying C memory structures are freed while the Ruby wrapper retains a dangling pointer. This results in memory corruption, invalid pointer dereferences, and application crashes during execution or garbage collection.

Vulnerability Overview

The Nokogiri library is a widely used Ruby gem for parsing, manipulating, and querying XML and HTML documents. To achieve high performance, Nokogiri relies on a native C extension that acts as a wrapper around the libxml2 library. This architecture divides application state into two distinct spaces: managed Ruby heap memory and unmanaged native system memory managed by libxml2.

The vulnerability designated as GHSA-PHWJ-RPRQ-35PP is a use-after-free (UAF) flaw classified under CWE-416. It resides within the native extension layer of Nokogiri that manages XML attribute nodes. Specifically, the flaw exists within the implementation of attribute value updates, where native memory deallocation is executed without checking the state of corresponding Ruby wrappers.

The attack surface is exposed when a Ruby application processes untrusted XML data, instantiates Ruby-side wrappers for the child nodes of XML attributes, and subsequently modifies those attributes. The resulting memory instability can be exploited to cause immediate application crashes, presenting a localized denial-of-service (DoS) vector.

Root Cause Analysis

The root cause of GHSA-PHWJ-RPRQ-35PP lies in the lifecycle mismatch between native libxml2 structures and Ruby proxy objects. When an XML attribute (xmlAttr) contains a text value, libxml2 represents this value internally as a linked list of child nodes (xmlNode). When a Ruby developer calls Nokogiri::XML::Attr#child or Attr#children, Nokogiri instantiates a Ruby object proxy wrapping the underlying native xmlNode structure.

To maintain a mapping between native nodes and their Ruby proxies, Nokogiri utilizes the _private field of the libxml2 xmlNode structure. This field contains a pointer back to the Ruby wrapper. This back-reference allows Nokogiri to return the same Ruby object when the same native node is accessed multiple times, preventing object duplication.

In vulnerable versions of Nokogiri, when the #value= or #content= methods are invoked on an attribute, the native C function set_value is executed in ext/nokogiri/xml_attr.c. This function immediately calls xmlFreeNodeList(attr->children) to clear the existing attribute contents from memory. The function fails to inspect the _private field of the child nodes being deallocated.

Consequently, if a child node has been wrapped in a Ruby object, the native node memory is freed, but the Ruby proxy object remains alive and active on the Ruby heap. The Ruby wrapper holds a now-dangling pointer to the deallocated C structure. Any subsequent read, write, or traversal operation involving this wrapper dereferences the invalid pointer, resulting in memory corruption or process termination.

Code-Level Patch Analysis

To understand the mechanical differences between the vulnerable and patched states, analyze the implementation of the attribute update process in ext/nokogiri/xml_attr.c. In the vulnerable code, the deallocation phase unconditionally cleans the linked list of child nodes.

The patch introduced in version 1.19.4 replaces the raw set_value function with noko_xml_attr_set_value and introduces a safety loop to inspect each child node before any deallocation occurs.

/* Unlink and pin any wrapped children */
xmlNode *cur = attr->children;
xmlNode *next;
 
while (cur) {
  next = cur->next;
  if (cur->_private) {
    xmlUnlinkNode(cur);
    noko_xml_document_pin_node(cur);
  }
  cur = next;
}

The added loop iterates over the linked list of children (attr->children). If cur->_private is evaluated as true, indicating that a Ruby wrapper exists, the code unlinks the node using xmlUnlinkNode(cur). This removes the node from the attribute's child list so that it will not be freed by subsequent mutation functions.

The unlinked node is then passed to noko_xml_document_pin_node(cur). This function registers the node within Nokogiri's document-level node cache. This action pins the node in native memory, ensuring its structure is preserved as long as the document or the corresponding Ruby proxy object exists, successfully eliminating the use-after-free condition.

Exploitation Methodology & Proof of Concept

Exploitation of GHSA-PHWJ-RPRQ-35PP requires a precise sequence of API interactions on a parsed XML structure. The initial prerequisite is the ingestion of an XML document containing an element with at least one attribute. The application must then access the attribute's children to initialize the Ruby proxy wrappers.

The following sequence represents a reliable proof of concept to demonstrate the vulnerability:

require 'nokogiri'
 
doc = Nokogiri::XML("<root target_attr='value_to_leak'/>")
attribute_node = doc.root.attribute("target_attr")
 
# This instantiates the Ruby-land proxy object
dangling_child = attribute_node.child
 
# This frees the native memory behind dangling_child
attribute_node.value = "new_replaced_value"
 
# Trigger Garbage Collection to force marking of the dangling pointer
GC.start(full_mark: true)
 
# Attempting to access the orphaned object triggers a segmentation fault
puts dangling_child.to_s

Upon executing the mutation step (attribute_node.value = "new_replaced_value"), the C memory representing 'value_to_leak' is reclaimed by the operating system allocator. The variable dangling_child continues to point to this address.

When GC.start is called, the Ruby virtual machine traverses active heap references to mark reachable objects. During this phase, or when explicitly invoking methods on dangling_child, the VM attempts to dereference the invalid address, causing an immediate segmentation fault.

Impact Assessment & Risk Vector

The security impact of GHSA-PHWJ-RPRQ-35PP is primarily confined to application availability. An unauthenticated remote attacker who can control XML inputs and influence the application's processing flow to trigger the vulnerable code path can cause the underlying Ruby process to terminate.

In environments running single-process web servers or worker queues, repeated process crashes can lead to a sustained denial-of-service condition. Because Nokogiri is heavily used in background jobs and document processors, this vulnerability presents an easy target for service disruption.

Achieving arbitrary code execution (RCE) via this use-after-free flaw is theoretically possible but highly complex in practice. The attacker would need to execute a precise heap grooming attack to reclaim the freed xmlNode memory allocation with controlled payload data before the pointer is dereferenced. This is difficult because of the asynchronous nature of Ruby's allocator and GC pauses.

The CVSS v4.0 score of 2.3 reflects this limited severity. The low rating is due to the high specificity of the required API usage pattern, which is not a standard pattern in most Nokogiri-based applications.

Mitigation and Defense-in-Depth

The definitive remediation for this vulnerability is to upgrade the Nokogiri dependency to version 1.19.4 or later. This release incorporates the defensive node unlinking and pinning logic in the CRuby native extension. JRuby environments are inherently unaffected as the Java-backed implementation of Nokogiri does not use this C extension.

If an immediate upgrade is not feasible, developers must audit their codebases to eliminate vulnerable API usage patterns. Avoid accessing attribute values via their child nodes. Instead, read and write attribute values using standard string-based interfaces.

# Vulnerable pattern
child_node = attr.child
attr.value = "new"
 
# Safe pattern
attr_value_string = attr.value
attr.value = "new"

To detect instances of this vulnerability dynamically during development, test suites can be executed under the control of AddressSanitizer (ASan). Compiling Ruby and Nokogiri with ASan enabled allows immediate detection of the use-after-free invalid memory read as soon as the attribute value is changed, providing detailed backtraces of the deallocation and access points.

Official Patches

Nokogiri MaintainersRelease comparison and commit logs containing the resolution patch.

Fix Analysis (1)

Technical Appendix

CVSS Score
2.3/ 10
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:U

Affected Systems

Nokogiri (CRuby implementations)

Affected Versions Detail

Product
Affected Versions
Fixed Version
Nokogiri
Nokogiri Maintainers
< 1.19.41.19.4
AttributeDetail
CWE IDCWE-416
Vulnerability ClassUse-After-Free (UAF)
CVSS Score2.3 (Low)
Attack VectorNetwork
Exploit StatusProof-of-Concept
KEV StatusNot Listed
Patched Version1.19.4

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Denial of Service
T1203Exploitation for Client Execution
Execution
CWE-416
Use After Free

Referencing memory after it has been freed, which can cause a program to crash, use unexpected values, or execute arbitrary code.

Known Exploits & Detection

GitHub Security AdvisoryVulnerability announcement containing reproduction methodology and code verification.

Vulnerability Timeline

Technical fix committed by Mike Dalessio
2026-06-14
Nokogiri version 1.19.4 is officially released
2026-06-18
GitHub Security Advisory GHSA-PHWJ-RPRQ-35PP is published
2026-06-19

References & Sources

  • [1]GHSA-PHWJ-RPRQ-35PP Security Advisory
  • [2]Nokogiri GitHub Repository
  • [3]Nokogiri 1.19.4 Patch Comparison

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-68945
8.8

CVE-2026-68945: Cache-Key Ambiguity in Angular HttpTransferCache Leading to State Poisoning

An in-depth technical analysis of CVE-2026-68945, a high-severity security vulnerability in Angular's `@angular/common/http` package. The flaw stems from an ambiguity in how query parameters are serialized to generate cache keys during Server-Side Rendering (SSR) within the `HttpTransferCache` component. By failing to encode delimiters and implicitly coercing arrays to comma-joined strings, the serialization mechanism yields identical cache keys for distinct requests, facilitating State Poisoning and Cross-Request Response Reuse.

Amit Schendel
Amit Schendel
3 views•5 min read
•about 3 hours ago•CVE-2026-43501
9.8

CVE-2026-43501: Heap Out-of-Bounds Write in Linux Kernel IPv6 RPL Segment Routing Header Processing

A critical heap out-of-bounds (OOB) write vulnerability exists in the Linux kernel's IPv6 RPL (Routing Protocol for Low-Power and Lossy Networks) Segment Routing Header (SRH) processing logic. The vulnerability is located within net/ipv6/exthdrs.c, specifically in the ipv6_rpl_srh_rcv function. Under specific circumstances, when a packet containing a compressed RPL Source Routing Header is processed, segment swapping can reduce the common-prefix length, causing the recompressed header to grow. Because the kernel fails to validate available headroom on intermediate segments, a buffer underflow occurs during skb_push. This leads to an integer wrap in the MAC header offset pointer during MAC header rebuilding, causing a 14-byte out-of-bounds memory write roughly 64 KiB past the socket buffer.

Alon Barad
Alon Barad
4 views•10 min read
•2 days ago•CVE-2026-58263
7.2

CVE-2026-58263: Mutation Cross-Site Scripting (mXSS) in Jodit Editor clean-html Sanitizer

CVE-2026-58263 is a high-severity Mutation Cross-Site Scripting (mXSS) vulnerability affecting Jodit Editor prior to version 4.12.28. The flaw exists in Jodit's built-in clean-html sanitizer plugin, which fails to securely parse and sanitize nested elements containing foreign namespaces like MathML and SVG. Attackers can bypass sanitization by smuggling malicious payload elements inside rawtext container tags like style inside a MathML node, leading to DOM mutation and unauthenticated arbitrary script execution in the context of the user's browser session.

Amit Schendel
Amit Schendel
10 views•6 min read
•2 days ago•CVE-2026-65841
5.3

CVE-2026-65841: Client-Side Cross-Site Scripting (XSS) via Foreign Namespace Sanitization Bypass in Jodit Editor

Jodit Editor versions prior to 4.13.6 are vulnerable to client-side Cross-Site Scripting (XSS). The clean-html plugin's sanitization routine performs case-sensitive lookups against uppercase-only element blacklists. When processing XML-based foreign namespaces such as SVG or MathML, DOM engines preserve the lowercase format of tags. Because Jodit's denyTags check fails to normalize tag casing, malicious script blocks nested inside foreign namespace elements completely bypass validation and serialize directly into the editor output.

Amit Schendel
Amit Schendel
7 views•6 min read
•2 days ago•CVE-2026-53510
8.1

CVE-2026-53510: Remote Code Execution via Dynamic WSDL Parsing in Savon Ruby SOAP Client

A critical code injection vulnerability exists in Savon, a widely used SOAP client library for Ruby, prior to version 2.17.2. The vulnerability resides within the Savon::Model.all_operations module, where operation names fetched from a target Web Services Description Language (WSDL) document are dynamically evaluated via module_eval without sanitization. An attacker capable of manipulating the target WSDL document (e.g., through Man-in-the-Middle attacks, DNS hijacking, or Server-Side Request Forgery) can execute arbitrary Ruby code in the context of the parent application process.

Alon Barad
Alon Barad
12 views•6 min read
•2 days ago•CVE-2026-53466
6.5

CVE-2026-53466: Integer Conversion Overflow in ImageMagick XCF Decoder

An integer conversion overflow vulnerability exists in the XCF decoder of ImageMagick before version 6.9.13-51 and 7.1.2-26. The issue arises from mixed-type arithmetic that promotes calculation results to floating-point representations, causing an undefined cast back to integer. Under optimizing compilers, this undefined behavior results in bounds checks being bypassed, allowing out-of-bounds heap reads.

Amit Schendel
Amit Schendel
6 views•6 min read