Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-55891

CVE-2026-55891: PrivateBin JSON-LD XSS Vulnerability

CVE-2026-55891 is a cross-site scripting flaw in PrivateBin that allows injection of arbitrary data into JSON-LD responses. This post explains its technical details, affected versions, and mitigation steps.

Published:

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.

php
// 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.
bash
# 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.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.