VYPR
Medium severity5.8GHSA Advisory· Published Jun 11, 2026· Updated Jun 11, 2026

CVE-2026-53723

CVE-2026-53723

Description

Guzzle Services prior to 1.5.4 fails to escape CDATA terminator in XML serialization, allowing injection of arbitrary XML elements into outgoing requests.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Guzzle Services prior to 1.5.4 fails to escape CDATA terminator in XML serialization, allowing injection of arbitrary XML elements into outgoing requests.

Vulnerability

In guzzlehttp/guzzle-services versions prior to 1.5.4, the XML request serializer uses XMLWriter::writeCData($value) to encode values containing <, >, or &. If an attacker-controlled input contains the CDATA terminator ]]>, the CDATA section closes prematurely and the remainder of the value is interpreted as raw XML markup. This affects applications that serialize outgoing requests with location: xml parameters where the value is serialized as XML element text (not an attribute) and the input is untrusted and not constrained by a safe enum, pattern, or custom filter that excludes ]]>. The downstream service must parse the generated XML structurally for the injection to have effect. [1][2][3]

Exploitation

An attacker needs to supply input containing ]]> in a parameter that is serialized as XML element text via location: xml. No special authentication is required if the application accepts untrusted input (e.g., user, tenant, or third-party data). The attacker does not need to control the service description or schema. The injected ]]> closes the CDATA section, and any subsequent characters become XML markup, allowing the attacker to insert arbitrary elements, attributes, or text nodes into the request body. [2][3]

Impact

Successful exploitation allows an attacker to inject arbitrary XML elements into the outgoing request body. Depending on the receiving service, this can alter operation semantics, smuggle privileged fields, bypass modeled parameter boundaries, or create conflicting duplicated elements. The vulnerability is an outgoing request-body integrity issue; it does not affect response parsing directly. However, second-order attacks are possible if attacker-controlled response XML is parsed and later used as a location: xml request parameter. [2][3]

Mitigation

The vulnerability is fixed in guzzlehttp/guzzle-services version 1.5.4. Users should upgrade to this version or later. As a workaround, ensure that any untrusted input used in location: xml parameters is constrained by a safe enum, pattern, or custom filter that excludes the ]]> sequence. Users who only use Guzzle Services to deserialize HTTP response bodies are not directly affected. [2][3]

AI Insight generated on Jun 11, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

1

Patches

1
d78052e3ccf1

Prevent XML CDATA injection (#259)

https://github.com/guzzle/guzzle-servicesGraham CampbellJun 2, 2026Fixed in 1.5.4via ghsa-release-walk
3 files changed · +73 1
  • CHANGELOG.md+4 0 modified
    @@ -1,5 +1,9 @@
     # CHANGELOG
     
    +## 1.5.4 - Upcoming
    +
    +* Prevent XML CDATA injection during request serialization (GHSA-q8r6-5hfw-5jff)
    +
     ## 1.5.3 - 2026-06-02
     
     * Harden request serialization state after failures
    
  • src/RequestLocation/XmlLocation.php+16 1 modified
    @@ -217,13 +217,28 @@ protected function writeElement(\XMLWriter $writer, $prefix, $name, $namespace,
                 $writer->startElement($name);
             }
             if ($value !== null && strpbrk($value, '<>&')) {
    -            $writer->writeCData($value);
    +            $this->writeSafeCData($writer, $value);
             } else {
                 $writer->writeRaw($value);
             }
             $writer->endElement();
         }
     
    +    protected function writeSafeCData(\XMLWriter $writer, $value)
    +    {
    +        $parts = explode(']]>', $value);
    +        $last = array_pop($parts);
    +
    +        foreach ($parts as $part) {
    +            $writer->writeCData($part.']]');
    +            $writer->writeCData('>');
    +        }
    +
    +        if ($last !== '') {
    +            $writer->writeCData($last);
    +        }
    +    }
    +
         /**
          * Create a new xml writer and start a document
          *
    
  • tests/RequestLocation/XmlLocationTest.php+53 0 modified
    @@ -524,4 +524,57 @@ public function testSerializesXml(array $operation, array $input, $xml)
                 $this->assertEquals($xml, $body);
             }
         }
    +
    +    /**
    +     * @group RequestLocation
    +     */
    +    public function testSplitsCDataTerminatorsToPreventXmlInjection()
    +    {
    +        $payload = 'x]]></Foo><Injected attr="1"/><Foo><![CDATA[y';
    +        $document = simplexml_load_string($this->serializeXmlValue($payload));
    +
    +        $this->assertNotFalse($document);
    +        $this->assertCount(1, $document->Foo);
    +        $this->assertCount(0, $document->Injected);
    +        $this->assertSame($payload, (string) $document->Foo);
    +    }
    +
    +    public function cdataTerminatorProvider()
    +    {
    +        return [
    +            ['a]]>b'],
    +            ['abc]]>'],
    +            [']]>'],
    +        ];
    +    }
    +
    +    /**
    +     * @dataProvider cdataTerminatorProvider
    +     *
    +     * @group RequestLocation
    +     */
    +    public function testPreservesTextContainingCDataTerminators($value)
    +    {
    +        $document = simplexml_load_string($this->serializeXmlValue($value));
    +
    +        $this->assertNotFalse($document);
    +        $this->assertSame($value, (string) $document->Foo);
    +    }
    +
    +    private function serializeXmlValue($value)
    +    {
    +        $location = new XmlLocation();
    +        $command = new Command('foo', ['Foo' => $value]);
    +        $request = new Request('POST', 'http://httbin.org');
    +        $param = new Parameter([
    +            'name' => 'Foo',
    +            'location' => 'xml',
    +            'type' => 'string',
    +        ]);
    +
    +        $location->visit($command, $request, $param);
    +        $request = $location->after($command, $request, new Operation());
    +
    +        return (string) $request->getBody();
    +    }
     }
    

Vulnerability mechanics

Root cause

"Missing sanitization of the CDATA terminator `]]>` in XML request serialization allows attacker-controlled input to close the CDATA section early and inject arbitrary XML markup."

Attack vector

An attacker supplies a string containing the CDATA terminator `]]>` as a value for a `location: xml` request parameter (e.g., `DisplayName`). The vulnerable serializer wraps the value in a CDATA section, but the embedded `]]>` closes the CDATA early, and the remainder of the string is interpreted as raw XML markup. This allows the attacker to inject arbitrary XML elements (e.g., `<Role>admin</Role>`) into the outgoing request body, potentially altering operation semantics or smuggling privileged fields [ref_id=1][ref_id=2].

Affected code

The vulnerability is in `src/RequestLocation/XmlLocation.php` in the `writeElement()` method. When a scalar XML element value contains `<`, `>`, or `&`, the method calls `XMLWriter::writeCData($value)` without sanitizing the CDATA terminator `]]>`. The patch introduces a `writeSafeCData()` helper that splits the value on `]]>` and writes each segment safely.

What the fix does

The patch in `XmlLocation.php` replaces the direct `$writer->writeCData($value)` call with a new `writeSafeCData()` method. This method splits the input on the `]]>` terminator, writes each part as a separate CDATA section (rejoining the terminator across two CDATA blocks), and thereby prevents premature closure of the CDATA section [patch_id=5594252]. The fix preserves the original scalar value exactly and prevents injection of arbitrary XML nodes.

Preconditions

  • configThe application uses guzzlehttp/guzzle-services to serialize outgoing requests.
  • configA request parameter or additionalParameters schema uses location: xml.
  • configThe value is serialized as XML element text (not an XML attribute).
  • inputThe value contains attacker-controlled input that is not constrained by a safe enum, pattern, or filter excluding ]]>.
  • networkThe downstream service parses the generated XML structurally and may act on injected elements.

Generated on Jun 11, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

2

News mentions

0

No linked articles in our index yet.