On July 27, 2026, JetBrains issued a security advisory for CVE-2026-63077, a critical unsafe deserialization vulnerability affecting its TeamCity product. This flaw allows an unauthenticated attacker to achieve remote code execution by exploiting the agent polling protocol. An attacker capable of reaching a TeamCity server via HTTP or HTTPS can execute operating system commands with the privileges of the TeamCity server process.
Initially, JetBrains reported no evidence of active exploitation. However, by August 5, 2026, the vulnerability was added to the CISA Known Exploited Vulnerabilities (KEV) catalog, confirming its active exploitation in the wild.
The vulnerability stems from how TeamCity, specifically versions prior to 2026.1.3, handles Java deserialization using the XStream library. TeamCity utilizes a central server to coordinate builds and separate build agents to execute them. Agents communicate with the server via an agent polling protocol, which operates over endpoints under `/app/agents/v1`. This communication channel is distinct from the TeamCity web interface or REST API, and access to many agent endpoints is unauthenticated.
XStream is a Java library designed to convert object graphs to XML and reconstruct them from XML. The core issue lies in TeamCity's wrapper for XStream, `jetbrains.buildServer.messages.XStreamHolder`. In vulnerable versions, such as 2026.1.2, this wrapper configures an XStream instance and then calls `setupSecurityIfNeeded()`. This method adds TeamCity's specific allowlist entries to XStream's default permissions without first clearing them.
The bundled XStream version 1.4.20.3, upon initialization, already permits several broad type hierarchies by default, including `Map` and `Throwable`. Because TeamCity's allowlist is appended to these existing permissions, rather than replacing them, the system does not operate on a deny-by-default baseline. This allows for unsafe deserialization.
The patch, implemented in TeamCity version 2026.1.3, addresses this by explicitly clearing XStream's default permissions before adding TeamCity's allowlist. The `setupSecurityIfNeeded()` method now includes a call to `xStream.addPermission(NoTypePermission.NONE)` if a new `isWhiteListForced` property is true, which it is by default. This ensures that the allowlist operates from an empty permission set, effectively removing the broad default permissions like `Map` and `Throwable`.
Permitting broad type hierarchies like `Map` and `Throwable` covers numerous implementations and subclasses. This exposure, combined with XStream's reflection converter handling of declared fields and object references, provides sufficient callbacks to construct a gadget chain for exploitation. An attacker can leverage XPath references within the XML object graph to reuse allocated objects without additional type checks, facilitating the deserialization of malicious payloads.






