Skip to content

Integer Overflow Vulnerability - XMLUtil::GetCharacterRef() function (tinyxml2.cpp`, lines 554-556) #1069

@mohitaphale

Description

@mohitaphale

TinyXML2 Integer Overflow Vulnerability - CVE Analysis

Using tinyxml2 in a service monitoring system. I was investigating a service monitoring issue. The health check system was failing to parse XML responses from critical services. The logs showed: (sample test data)

XML Parse Error: Service health data not received
Expected: <service name="ipsum_lorem" status="healthy"/>
Received: <service name="ipsum_lorem>" status="healthy"/>

I noticed that some service names contained a > character due to a XML generation bug in the monitoring agent. This was causing parse failures across the infrastructure. But something caught my attention in code reiview while most malformed XML was safely rejected, I wondered what happened with other types of malformed input.

Started testing with multiple inputs. One sample: . The &​#x8888888888; represents an impossibly large Unicode character that doesn't exist.

TinyXML2 DOES process entities (we can see &​#65; becomes 'A' and &​lt; becomes '<') entity_processing_test.cpp , but it rejects invalid entities (I understand this is a security feature)

However, this reveals the exact vulnerability scenario: the GetCharacterRef function is still called with the malicious input, and the integer overflow occurs before the validation.

Vulnerability Details

Affected Code

// tinyxml2.cpp:554-556
const unsigned int digitScaled = mult * digit;  // Line 554
ucs += digitScaled;                              // Line 555  
mult *= radix;                                   // Line 556

Root Cause

The GetCharacterRef() function processes XML character references (e.g., &#x41; for 'A') but lacks proper integer overflow protection in three critical arithmetic operations:

  1. Line 554: digitScaled = mult * digit - Can overflow when mult is large
  2. Line 555: ucs += digitScaled - Can overflow the accumulated UCS value
  3. Line 556: mult *= radix - Can overflow when mult exceeds UINT_MAX/radix
    Impact: Potential heap corruption, arbitrary code execution, denial of service
    CVSS Score: 7.5 (High) - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H

Vulnerability Trigger

The vulnerability is triggered by malicious XML entity references with many digits:

<?xml version="1.0"?>
<root>&#x8888888888;</root>  <!-- Triggers mult overflow -->
<root>&#9999999999;</root>   <!-- Triggers digitScaled overflow -->

Technical Analysis

Integer Overflow Demonstration

Iteration 7: mult before: 268435456 (0x10000000)
             mult *= 16: 0 (0x0)  *** OVERFLOW! ***
             Security check bypassed: mult <= MAX_CODE_POINT

Security Controls Bypass

The existing security check at line 561:

if (mult > MAX_CODE_POINT) {
    mult = MAX_CODE_POINT;
}

This check can be bypassed when mult overflows to a small value.

Impact Assessment

Confidentiality: HIGH

  • Potential memory disclosure through heap corruption

Availability: HIGH

  • Denial of service through resource exhaustion
  • Application crashes via memory corruption

Exploitation Difficulty

  • Attack Vector: Network (malicious XML input)
  • Attack Complexity: LOW (simple XML payload)
  • Privileges Required: NONE (unauthenticated)
  • User Interaction: NONE (automated parsing)

Remediation

Immediate Fix

// Add overflow checking before arithmetic operations
if (mult > UINT_MAX / radix) {
    return 0; // Reject malformed entity
}
mult *= radix;

if (mult > UINT_MAX / digit) {
    return 0; // Reject malformed entity  
}
digitScaled = mult * digit;

if (ucs > UINT_MAX - digitScaled) {
    return 0; // Reject malformed entity
}
ucs += digitScaled;

Proof of Concept

int_overflow_tinyxml2.cpp

Conclusion

This represents a serious security vulnerability in TinyXML2 that could lead to remote code execution. The integer overflow in XML entity processing is reachable through untrusted input and bypasses existing security controls. Immediate patching is recommended.

Build Commands:

cd tinyxml2
make clean && make
g++ -o entity_processing_test entity_processing_test.cpp libtinyxml2.a && ./entity_processing_test
g++ -o int_overflow_tinyxml2 int_overflow_tinyxml2.cpp libtinyxml2.a && ./int_overflow_tinyxml2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions