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·17 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 9 hours ago•CVE-2026-54068
5.9

CVE-2026-54068: Unauthenticated Server-Side Template Injection and SQLite Exfiltration in SiYuan PKM

An authentication bypass in the SiYuan personal knowledge management system before version 3.7.0 exposes a dynamic icon rendering endpoint. This endpoint processes client-supplied Go template directives. By submitting a crafted request, an unauthenticated remote attacker can leverage registered database template functions to execute arbitrary read-only SQL queries and exfiltrate workspace contents.

Amit Schendel
Amit Schendel
5 views•5 min read
•about 10 hours ago•CVE-2026-54069
9.1

CVE-2026-54069: Authentication Bypass in SiYuan Note via Origin Header Spoofing

CVE-2026-54069 is a critical authentication bypass vulnerability in the SiYuan Note personal knowledge management system. The flaw is located in the HTTP server's middleware handling API authorization, which unconditionally trusts requests carrying a 'chrome-extension://' scheme in the Origin HTTP header, granting administrative access without validating API tokens.

Alon Barad
Alon Barad
4 views•5 min read
•about 10 hours ago•CVE-2026-54089
9.1

CVE-2026-54089: Authentication Bypass by Spoofing in File Browser

CVE-2026-54089 is a critical authentication bypass vulnerability in File Browser affecting instances configured with proxy-based authentication. An unauthenticated remote attacker with direct network access can impersonate arbitrary users or register new accounts by spoofing configured HTTP headers.

Amit Schendel
Amit Schendel
4 views•7 min read
•about 11 hours ago•GHSA-99J7-FHR2-XFJ4
10.0

GHSA-99J7-FHR2-XFJ4: Malicious Remote Code Execution Payload in 'exploration' Cargo Crate

The malicious Cargo package 'exploration' was uploaded to the crates.io registry. During compilation or package import, the crate executes code designed to establish an outbound TCP/HTTP connection, download an external second-stage binary, and execute the binary locally on the host machine. This creates an unauthenticated remote code execution vector impacting developer environments and continuous integration pipelines.

Amit Schendel
Amit Schendel
7 views•6 min read
•about 11 hours ago•CVE-2026-54088
9.3

CVE-2026-54088: Pre-Authentication Remote Code Execution in File Browser Hook Authentication

CVE-2026-54088 is a critical command injection vulnerability in File Browser prior to version 2.63.6. When Hook Authentication is enabled, the application interpolates unsanitized credentials into a shell command, allowing unauthenticated remote code execution.

Alon Barad
Alon Barad
6 views•6 min read
•about 12 hours ago•GHSA-QV4M-M73M-8HJ7
8.8

GHSA-qv4m-m73m-8hj7: Authenticated Arbitrary File Upload leading to Remote Code Execution in NotrinosERP

An authenticated remote code execution vulnerability exists in NotrinosERP (versions up to and including 1.0.0) within the Human Resource Management (HRM) module. Users with employee management permissions can upload arbitrary file types, including PHP scripts, which are written directly to a web-accessible directory. This allows for arbitrary code execution in the context of the web-server user.

Alon Barad
Alon Barad
5 views•6 min read