Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐘
🐘 Packagist
Not in CISA KEV
NONE severity

CVE-2026-55891 — privatebin

NONEFix: PrivateBin/PrivateBin@164c839

CVE-2026-55891 is a none-severity (CVSS 0) CWE-116 vulnerability in privatebin/privatebin. A fix is available for privatebin/privatebin — see the affected versions and patch details below.

PrivateBin: Reflected JSON injection in backend responses via unescaped REQUEST_URI

Also known asGHSA-xrjc-c68j-hp7w
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 12, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-55891.

EPSS Exploitation Probability

via FIRST.org ↗
0.5%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs44th percentile — riskier than 44% of all scored CVEsHighest risk
0.00%0.35%0.69%1.04%0.3%0.5%0.5%Sep 26Oct 26Oct 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

CVE-2026-55891 by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.

Where this sits among everything scored

Of 385,987 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.

Real-World Exposure

1 pkg affected
🐘privatebin/privatebin

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Packagist packages — download data is not available via public APIs for these ecosystems.

Description

Vulnerability Details

A reflected JSON injection allows an attacker to return arbitrary data in the JSON endpoints (like /?jsonld= and /?pasteid).

Root Cause

Request::getRequestUri() sanitizes $_SERVER['REQUEST_URI'] with FILTER_SANITIZE_URL:

public function getRequestUri()
{
    $uri = array_key_exists('REQUEST_URI', $_SERVER) ? filter_var($_SERVER['REQUEST_URI'], FILTER_SANITIZE_URL) : '';
    return empty($uri) ? '/' : $uri;
}

FILTER_SANITIZE_URL does not strip ", ', <, > characters (per the PHP manual's allowed-character list for this filter). So the raw, attacker-controlled request URI (including query string) passes through almost unmodified into Controller::$_urlBase (set in _init()).

In Controller::_jsonld(), $_urlBase is spliced directly into one of the static .jsonld templates (js/types.jsonld, js/paste.jsonld, etc.) with a plain str_replace(), without any JSON-escaping:

$content = str_replace(
    '?jsonld=',
    $this->_urlBase . '?jsonld=',
    file_get_contents($file)
);
...
header('Content-type: application/ld+json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET');
echo $content;

A request URI containing a literal " therefore breaks out of the JSON string in the "@context"."pb" value and injects arbitrary attacker-controlled key/value pairs into the response body, which is served with Content-Type: application/ld+json and Access-Control-Allow-Origin: *.

Additionally, the jsonld case in Controller::__construct() returns early:

case 'jsonld':
    $this->_jsonld($this->_request->getParam('jsonld'));
    return;

This bypasses _setCacheHeaders() and all of the security headers normally applied in _view() (notably X-Content-Type-Options: nosniff, CSP, X-Frame-Options, Referrer-Policy). So this is the only response path lacking X-Content-Type-Options: nosniff.

Attack Scenario

  1. An attacker crafts a request to the target PrivateBin instance whose request-target contains a raw " character, e.g.: GET /?jsonld=types&x="injected":"pwned","y":" HTTP/1.1 (delivered via a raw socket / HTTP client that doesn't normalize the request line — most browsers percent-encode " in the address bar, but many HTTP libraries, proxies, and automated link-preview/structured-data crawlers do not).
  2. The server reflects the raw value into the JSON-LD response, producing a syntactically broken / attacker-extended JSON document.
  3. Because Access-Control-Allow-Origin: * is set and X-Content-Type-Options: nosniff is missing on this path, any origin can fetch and rely on this manipulated content, and the response loses the defense-in-depth MIME-sniffing protection applied everywhere else in the app.

Impact

Reflected, unauthenticated injection of attacker-controlled content into a CORS-open application/ld+json response, plus a missing X-Content-Type-Options: nosniff header on this single response path (present everywhere else). No direct script execution was demonstrated on current browsers (this content type is generally not HTML-sniffed), but it is a real output-encoding bug (CWE-116) and a defense-in-depth gap that could be exploited by structured-data consumers or in combination with other issues / less-strict clients.

Vulnerable Code

$content = str_replace(
    '?jsonld=',
    $this->_urlBase . '?jsonld=',
    file_get_contents($file)
);
...
header('Content-type: application/ld+json');

Verification

Dynamically confirmed on v2.0.4 (commit 597a6f0) via php -S 127.0.0.1:8082 index.php:

Request:

GET /?jsonld=types&x="injected":"pwned","y":" HTTP/1.1
Host: 127.0.0.1:8082
Connection: close

Unpatched response body (excerpt):

"pb": "/?jsonld=types&x="injected":"pwned","y":"?jsonld=types#"

— i.e. the " characters are reflected raw, breaking the JSON structure, and X-Content-Type-Options is absent from the response headers.

After applying the fix above, the same request returns:

"pb": "/?jsonld=types&x=\"injected\":\"pwned\",\"y\":\"?jsonld=types#"

with X-Content-Type-Options: nosniff present, and the existing JsonApiTest::testJsonLd* unit test expectations (/?jsonld=...) remain unchanged for normal requests.

Credits

This vulnerability was reported by Iaohkut, @alanturing881, which PrivateBin would like to thank for that. In general, PrivateBin would like to thank everyone reporting issues and potential vulnerabilities to it.

If you think you have found a vulnerability or potential security risk, we'd kindly ask you to follow our security policy and report it to us. PrivateBin then assess the report and will take the actions PrivateBin deem necessary to address it.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐘Packagistprivatebin/privatebinall versions2.0.5composer require privatebin/privatebin:^2.0.5

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for privatebin/privatebin, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update privatebin/privatebin to 2.0.5 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-55891 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

Frequently Asked Questions

## Vulnerability Details A reflected JSON injection allows an attacker to return arbitrary data in the JSON endpoints (like ` /?jsonld=` and `/?pasteid`). ### Root Cause `Request::getRequestUri()` sanitizes `$_SERVER['REQUEST_URI']` with `FILTER_SANITIZE_URL`: ```php public function getRequestUri() { $uri = array_key_exists('REQUEST_URI', $_SERVER) ? filter_var($_SERVER['REQUEST_URI'], FILTER_SANITIZE_URL) : ''; return empty($uri) ? '/' : $uri; } ``` `FILTER_SANITIZE_URL` does **not** strip `"`, `'`, `<`, `>` characters (per the PHP manual's allowed-character list for this filter)
O3 Security · Impact-Aware SCA

Is CVE-2026-55891 in your dependencies?

Find it across Packagist, including transitive dependencies.

CVE-2026-55891: privatebin — Fixed in 2.0.5