CVE-2026-55891 Overview
CVE-2026-55891 affects PrivateBin, an open-source pastebin where the server has zero knowledge of pasted data. Versions prior to 2.0.5 improperly sanitize the request URI before embedding it into JSON-LD responses. The Request::getRequestUri() method in lib/Request.php passes $_SERVER['REQUEST_URI'] through FILTER_SANITIZE_URL, which does not strip quotation marks, angle brackets, or apostrophes. The attacker-controlled value is later inserted without JSON escaping into application/ld+json responses, allowing injection of arbitrary key-value pairs. The issue is fixed in PrivateBin 2.0.5.
Critical Impact
A raw quotation mark in the request target can break out of the JSON string in CORS-open application/ld+json responses, enabling data injection into structured-data consumers.
Affected Products
- PrivateBin versions prior to 2.0.5
- lib/Request.php component (getRequestUri())
- lib/Controller.php component (_jsonld() and JSON-LD templates)
Discovery Timeline
- 2026-08-28 - CVE-2026-55891 published to NVD
- 2026-08-31 - Last updated in NVD database
Technical Details for CVE-2026-55891
Vulnerability Analysis
The flaw is an output encoding failure classified as [CWE-116]. Request::getRequestUri() sanitizes $_SERVER['REQUEST_URI'] with PHP's FILTER_SANITIZE_URL. This filter preserves quotation marks, angle brackets, and apostrophes, which are all significant characters in JSON and HTML contexts. Controller::_init() stores the resulting value in Controller::$_urlBase. Controller::_jsonld() in lib/Controller.php then uses str_replace() to interpolate that value into js/types.jsonld, js/paste.jsonld, and other JSON-LD templates served by /?jsonld= and /?pasteid.
Because the interpolation does not perform JSON escaping, an attacker-supplied quotation mark closes the enclosing JSON string. The attacker can then append arbitrary key-value pairs to the response document. The jsonld branch in Controller::__construct() returns before _setCacheHeaders(), so the response also omits X-Content-Type-Options: nosniff, Content Security Policy, X-Frame-Options, and Referrer-Policy headers. Direct script execution was not demonstrated, but manipulated responses can affect structured-data consumers and combine with lenient clients.
Root Cause
The root cause is reliance on FILTER_SANITIZE_URL as a security boundary for a value that is later embedded into a JSON string via string replacement. URL sanitization and JSON string escaping are different operations. The vulnerable code path also fails to apply the standard security response headers to JSON-LD responses.
Attack Vector
An attacker sends an HTTP request with a crafted REQUEST_URI containing a raw quotation mark. This can be delivered by an HTTP client, proxy, or structured-data crawler that does not normalize the request target. When the server generates the JSON-LD response for /?jsonld= or /?pasteid, the injected characters escape the JSON string context. Because the response is served with permissive CORS headers, cross-origin consumers may ingest the manipulated structured data.
// Security patch in lib/Request.php
// Returns the request URI path only, without GET parameters
public function getRequestUri()
{
$uri = array_key_exists('REQUEST_URI', $_SERVER) ? filter_var($_SERVER['REQUEST_URI'], FILTER_SANITIZE_URL) : '';
return empty($uri) ? '/' : parse_url($uri, PHP_URL_PATH);
}
Source: PrivateBin patch commit 164c839. The fix restricts the returned value to the URL path component, discarding query parameters and any injected characters outside the path.
Detection Methods for CVE-2026-55891
Indicators of Compromise
- HTTP requests to PrivateBin instances containing raw quotation marks, angle brackets, or apostrophes in the request target.
- Access log entries targeting /?jsonld= or /?pasteid paths with unusual characters in the URI.
- application/ld+json responses missing X-Content-Type-Options, CSP, X-Frame-Options, or Referrer-Policy headers.
Detection Strategies
- Inspect web server access logs for encoded and raw special characters in the REQUEST_URI targeting JSON-LD endpoints.
- Compare deployed PrivateBin versions against 2.0.5 across all hosted instances.
- Monitor outbound structured-data crawler requests to identify clients that fail to normalize URIs.
Monitoring Recommendations
- Deploy web application firewall rules that reject unencoded quotation marks and angle brackets in request URIs.
- Alert on JSON-LD responses whose payload includes unexpected keys outside the documented schema.
- Track PrivateBin release channels for further security advisories.
How to Mitigate CVE-2026-55891
Immediate Actions Required
- Upgrade all PrivateBin deployments to version 2.0.5 or later.
- Audit web server and reverse proxy configurations to confirm they normalize or reject malformed request URIs.
- Review historical access logs for prior injection attempts against /?jsonld= and /?pasteid endpoints.
Patch Information
The fix is available in PrivateBin Release 2.0.5. The corrective change is documented in GitHub Security Advisory GHSA-xrjc-c68j-hp7w and applied in commit 164c839. The patch modifies getRequestUri() to return only the URL path via parse_url($uri, PHP_URL_PATH).
Workarounds
- Place PrivateBin behind a reverse proxy that strictly validates and normalizes request URIs before forwarding.
- Configure the web server to reject requests containing raw quotation marks or angle brackets in the URI.
- Disable or restrict access to the JSON-LD endpoints until the upgrade is applied.
# Example nginx rule to reject suspicious characters in the request URI
if ($request_uri ~* "[\"'<>]") {
return 400;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

