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

CVE-2026-47110: Tiptap for PHP DoS Vulnerability

CVE-2026-47110 is a denial of service flaw in Tiptap for PHP that allows authenticated attackers to crash the HTML rendering pipeline by submitting malformed JSON. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-47110 Overview

CVE-2026-47110 is a denial of service vulnerability in Tiptap for PHP versions prior to 2.1.1. The flaw resides in the Link::isAllowedUri() function, which passes the attrs.href field directly to preg_match() without validating that the value is a string. Authenticated attackers can submit Tiptap JSON containing an array in the attrs.href field, triggering an unhandled TypeError. Because the malformed JSON can be persisted in the database, every subsequent attempt to render the affected record will crash the server-side HTML rendering pipeline. The condition persists until an administrator manually repairs the database entry.

Critical Impact

Authenticated attackers can persistently break the HTML rendering pipeline for any record containing a malformed href array, denying service to all viewers until manual database remediation occurs.

Affected Products

  • Tiptap for PHP versions before 2.1.1
  • Applications integrating ueberdosis/tiptap-php for content rendering
  • PHP backends performing server-side rendering of Tiptap JSON documents

Discovery Timeline

  • 2026-06-24 - CVE-2026-47110 published to NVD
  • 2026-06-24 - Last updated in NVD database

Technical Details for CVE-2026-47110

Vulnerability Analysis

The vulnerability is classified under [CWE-241] (Improper Handling of Unexpected Data Type). Tiptap for PHP converts ProseMirror/Tiptap JSON documents into HTML by walking the node tree and applying registered marks. The Link mark validates URIs through Link::isAllowedUri(), which is invoked during HTML generation.

The function assumes attrs.href is always a string and forwards the value to preg_replace() and preg_match(). PHP's PCRE functions require a string $subject argument. When an array is supplied, PHP 8 raises an uncaught TypeError, terminating the request with a fatal error.

Because Tiptap content is typically stored in a database after client submission, an attacker can poison a single record. Every subsequent render request for that record triggers the same TypeError, producing a persistent denial of service against all users who view the affected content.

Root Cause

The root cause is missing type validation on user-controlled input before passing it to PCRE functions. The attrs.href attribute is treated as trusted string data, but the JSON specification permits any value type. No is_string() guard existed prior to version 2.1.1, allowing arrays, objects, or other non-string values to reach preg_match().

Attack Vector

An authenticated attacker submits a Tiptap JSON document where a link mark contains a non-string href, for example "attrs": { "href": ["https://example.com"] }. The application stores the document. Any subsequent rendering operation invokes Link::isAllowedUri() and crashes with a TypeError, producing HTTP 500 responses for every viewer of that record.

php
// Security patch in src/Marks/Link.php
// Source: https://github.com/ueberdosis/tiptap-php/commit/74bfb7be1c8c6102b240f3879b7f984a6ab87b97

            return true;
        }

+       if (! is_string($uri)) {
+           return false;
+       }
+
        $sanitised = preg_replace(self::ATTR_WHITESPACE, '', $uri);

        $pattern = '/^(?:(?:' . implode('|', array_map('preg_quote', $this->options['allowedProtocols']))

The patch adds an is_string() guard that returns false for any non-string $uri, preventing the TypeError from reaching preg_replace() and preg_match().

Detection Methods for CVE-2026-47110

Indicators of Compromise

  • PHP error logs containing TypeError exceptions originating in Link::isAllowedUri() or preg_match() with array argument messages
  • HTTP 500 responses correlated with rendering requests for specific content records
  • Stored Tiptap JSON documents where attrs.href is an array, object, or non-string scalar
  • Repeated render failures isolated to individual database entries rather than systemwide errors

Detection Strategies

  • Scan persisted Tiptap JSON columns for href attributes whose value is not a JSON string, using database queries or JSON path expressions
  • Add application-layer logging that captures the document ID and submitting user when isAllowedUri() returns false or throws
  • Alert on spikes of HTTP 500 responses tied to content rendering endpoints in the web tier

Monitoring Recommendations

  • Forward PHP error_log output to a centralized logging system and create alerts on TypeError in tiptap-php namespaces
  • Track per-record render failure rates to identify poisoned database entries quickly
  • Monitor authenticated content submission endpoints for malformed JSON structures and rate-limit abusive accounts

How to Mitigate CVE-2026-47110

Immediate Actions Required

  • Upgrade ueberdosis/tiptap-php to version 2.1.1 or later via Composer
  • Audit existing stored Tiptap documents for non-string href values and repair or remove affected records
  • Review authenticated user submission paths to identify accounts that may have planted malformed documents
  • Restrict content submission privileges to trusted roles until the upgrade is deployed

Patch Information

The fix is available in Tiptap for PHP release 2.1.1 and was merged via pull request #94. The change is implemented in commit 74bfb7be, which adds an is_string() check in src/Marks/Link.php before invoking PCRE functions. Additional context is available in the VulnCheck advisory.

Workarounds

  • Validate Tiptap JSON server-side before storage, rejecting documents where any attrs.href is not a string
  • Wrap calls into the Tiptap renderer with a try/catch for TypeError to degrade gracefully while remediating
  • Apply a custom subclass or extension override of Link::isAllowedUri() that enforces is_string() if upgrading is not immediately feasible
bash
# Configuration example: upgrade and verify version
composer require ueberdosis/tiptap-php:^2.1.1
composer show ueberdosis/tiptap-php | grep versions

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.