CVE-2026-76572 Overview
CVE-2026-76572 is an XML External Entity (XXE) vulnerability in the Public Knowledge Project (PKP) pkp-lib library. The flaw resides in the _transformPHP function of classes/xslt/XSLTransformer.php. The library configures the underlying DOMDocument parser with substituteEntities and resolveExternals enabled, allowing external XML entities to be resolved during transformation.
Affected releases include pkp-lib up to 3.3.0-22, 3.4.0-10, and 3.5.0-4. An authenticated remote attacker can supply crafted XML input to trigger external entity resolution [CWE-610]. The issue is fixed in 3.3.0-23, 3.4.0-11, and 3.5.0-5.
Critical Impact
Successful exploitation allows attackers to read local files, perform Server-Side Request Forgery (SSRF), and disclose sensitive information from the host running the affected PKP application.
Affected Products
- PKP pkp-lib versions up to and including 3.3.0-22
- PKP pkp-lib versions up to and including 3.4.0-10
- PKP pkp-lib versions up to and including 3.5.0-4
Discovery Timeline
- 2026-08-19 - CVE-2026-76572 published to NVD
- 2026-08-20 - Last updated in NVD database
Technical Details for CVE-2026-76572
Vulnerability Analysis
The vulnerability exists in the XSLT transformation pipeline implemented in classes/xslt/XSLTransformer.php. The _transformPHP method instantiates a DOMDocument and enables entity substitution and external reference resolution before loading attacker-controlled XML through loadXML(). When the parser encounters a DOCTYPE declaration with an external entity, it dereferences the specified URI. Attackers use this behavior to read files on the server or force outbound network requests. The PKP suite powers Open Journal Systems (OJS), Open Monograph Press (OMP), and Open Preprint Systems (OPS), which makes this parser reachable from many scholarly publishing deployments.
Root Cause
The defect maps to Externally Controlled Reference to a Resource in Another Sphere [CWE-610]. The DOM parser was explicitly configured with substituteEntities = true and resolveExternals = true, and the call to loadXML() did not pass LIBXML_NONET to block network entity retrieval. This combination allows any XML payload processed by the transformer to reference and expand external entities.
Attack Vector
The attack is remote and network-based but requires high privileges, meaning the attacker must reach an XSLT transformation endpoint accessible to authenticated users. Crafted XML containing an external entity declaration is submitted to any workflow that funnels input into XSLTransformer::_transformPHP. Upon load, the parser retrieves the referenced URI, embedding file contents or SSRF responses into the resulting DOM.
// Security patch in classes/xslt/XSLTransformer.php
// Source: https://github.com/pkp/pkp-lib/commit/78c699370ea43ae2784e1c4ace7c947d207f2b47
// Instantiate and configure the result DOM
$resultDOM = new DOMDocument('1.0', static::XSLT_PROCESSOR_ENCODING);
$resultDOM->recover = true;
- $resultDOM->substituteEntities = true;
- $resultDOM->resolveExternals = true;
// Load the XML and return the DOM
- $resultDOM->loadXML($resultXML);
+ $resultDOM->loadXML($resultXML, LIBXML_NONET | LIBXML_NOENT);
return $resultDOM;
default:
The fix removes the two unsafe DOMDocument flags and passes LIBXML_NONET to loadXML(), which blocks the libxml parser from making outbound network requests when resolving entities.
Detection Methods for CVE-2026-76572
Indicators of Compromise
- Inbound HTTP requests containing XML payloads with <!DOCTYPE ... [ <!ENTITY ... SYSTEM "..."> declarations targeting PKP endpoints.
- Unexpected outbound network connections from the PHP-FPM or web server process to attacker-controlled hosts shortly after XSLT operations.
- Web server logs showing successful authenticated requests to XSLT-driven workflows followed by anomalous file reads of /etc/passwd, application configuration, or credential files.
Detection Strategies
- Inspect application and reverse-proxy logs for XML request bodies containing SYSTEM or PUBLIC external entity keywords sent to OJS, OMP, or OPS instances.
- Compare the deployed pkp-lib version reported by the application against the patched releases 3.3.0-23, 3.4.0-11, and 3.5.0-5.
- Alert on any invocation of DOMDocument::loadXML in PKP application logs where resolveExternals or substituteEntities flags are set at runtime.
Monitoring Recommendations
- Enable web application firewall (WAF) rules that flag XML payloads containing ENTITY declarations with SYSTEM identifiers.
- Monitor egress traffic from PKP application servers and baseline expected destinations to surface SSRF attempts.
- Track file access patterns for sensitive paths such as /etc/passwd, /proc/self/environ, and application configuration files by the web service account.
How to Mitigate CVE-2026-76572
Immediate Actions Required
- Upgrade pkp-lib and any dependent applications (OJS, OMP, OPS) to 3.3.0-23, 3.4.0-11, or 3.5.0-5 as appropriate for your release branch.
- Restrict access to authenticated XSLT-driven workflows to trusted editorial roles until patching is complete.
- Review web server logs for prior XML payloads containing external entity declarations to identify possible exploitation attempts.
Patch Information
The upstream fix is committed as 78c699370ea43ae2784e1c4ace7c947d207f2b47 in the PKP pkp-lib repository. The patch is included in release 3.5.0-5 and the corresponding 3.3.0-23 and 3.4.0-11 maintenance releases. See the associated issue tracker entry #12977 for context.
Workarounds
- If patching cannot be applied immediately, manually edit classes/xslt/XSLTransformer.php to remove the substituteEntities and resolveExternals assignments and pass LIBXML_NONET | LIBXML_NOENT to loadXML() as shown in the upstream commit.
- Deploy a WAF rule that rejects request bodies containing <!ENTITY or SYSTEM/PUBLIC identifiers on PKP endpoints.
- Block outbound network access from the PKP application server to arbitrary destinations to limit SSRF impact until the patch is deployed.
# Verify the patched pkp-lib version is installed
cd /path/to/pkp-application
git -C lib/pkp log --oneline | grep 78c699370ea43ae2784e1c4ace7c947d207f2b47
# Alternative: check the release tag
git -C lib/pkp describe --tags
# Expected output: 3_5_0-5 (or 3_4_0-11 / 3_3_0-23)
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

