← Back to Feed CACHED · 2026-10-07 04:54:10 · CACHE_KEY CVE-2026-63077
CVE-2026-63077 · CWE-502 · Disclosed 2026-07-27

JetBrains TeamCity On-Premises Unauthenticated RCE via Agent Polling Protocol XStream Deserialization

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

Someone left the keys to the factory floor hanging on the front door, and the burglars already walked in

CVE-2026-63077 is an unauthenticated remote code execution vulnerability in all versions of JetBrains TeamCity On-Premises prior to 2026.1.3 and 2025.11.7. The flaw lives in the agent polling protocol — the HTTP channel build agents use to talk to the central server. TeamCity's XStreamHolder class fails to reset XStream's default type permissions before applying its allowlist, leaving the Map and Throwable hierarchies wide open for deserialization. An attacker sends a crafted XML payload to /app/agents/v1/commands/error (after a trivial unauthenticated agent registration at /app/agents/v1/register) and chains three gadgets — HSQLMetadataStorage$SchemaMismatchException, a FreeMarker BooleanModel/HashAdapter wrapper, and a TiedMapEntry in a HashSet — to trigger BasicDataSource.getConnection(), which executes attacker-controlled HSQLDB SQL. That SQL writes a .jspws webshell to the Tomcat webroot, bypassing TeamCity's JSP auth check entirely. The result: arbitrary OS command execution as the TeamCity server process, with full access to credentials, build configurations, and artifact stores.

The vendor's CRITICAL / 9.8 rating is completely justified and may even understate the real-world blast radius. This is not a theoretical chain — it is unauthenticated, requires zero user interaction, has trivial complexity, and public PoCs with mass-scanning capability have been available since early August 2026. CISA added it to KEV on August 5, and by September 24 confirmed ransomware operators are actively exploiting it. TeamCity is a CI/CD platform used by 30,000+ DevOps teams including Citibank, Tesla, Amazon Games, and Samsung. Compromising a TeamCity server gives an attacker supply-chain-scale impact: credential theft, build artifact tampering, and lateral movement into every environment that trusts CI/CD output. The historical precedent is APT29 mass-exploiting CVE-2024-27198 (a prior TeamCity auth bypass) for exactly this kind of supply-chain access.

"Unauth RCE in your CI/CD server. Ransomware crews already inside. Patch today."
02 · The Attack Path

6 steps from start to impact.

STEP 01

Unauthenticated agent registration

The attacker sends a POST to /app/agents/v1/register with arbitrary agent metadata. The TeamCity server returns a valid TeamCity-AgentSessionId header. No credentials, API keys, or prior access are required — this endpoint is intentionally unauthenticated because build agents need to self-register.
Conditions required:
  • HTTP/HTTPS network access to the TeamCity server on its configured port (default 8111)
Where this breaks in practice:
  • TeamCity must be reachable from the attacker's network — internet-facing or post-initial-access internally
Detection/coverage: Web server access logs will show POST to /app/agents/v1/register from an unexpected source IP. No standard IDS signature at this step alone.
STEP 02

Craft XStream deserialization payload

Using the publicly available Rapid7 PoC or one of several GitHub repos (0xCyp1337/CVE-2026-63077, AnggaTechI/CVE-2026-63077), the attacker constructs a three-entry LinkedHashMap XML payload. Entry 1 uses HSQLMetadataStorage$SchemaMismatchException (accepted under the Throwable hierarchy) to reach a BasicDataSource with attacker-controlled HSQLDB connection parameters. Entry 2 wraps it in a FreeMarker HashAdapter/BooleanModel. Entry 3 inserts a TiedMapEntry into a HashSet to trigger hashCode() → getValue() → getConnection().
Conditions required:
  • Knowledge of the gadget chain (publicly documented since August 2026)
Where this breaks in practice:
  • None — multiple turnkey exploit scripts exist with interactive shell and mass-scanning modes
STEP 03

Send payload to error-command endpoint

The attacker POSTs the malicious XML to /app/agents/v1/commands/error with the TeamCity-AgentSessionId header from Step 1. The server deserializes the XML via XStream, triggering the gadget chain. Because default XStream type permissions were never cleared, the attacker's classes pass the type check.
Conditions required:
  • Valid session ID from Step 1
  • HTTP access to the same server
Where this breaks in practice:
  • None — single HTTP request, no timing or race condition
Detection/coverage: TeamCity server logs will show ForbiddenClassException or ConversionException referencing HSQLMetadataStorage$SchemaMismatchException or BasicDataSource wrapped into f.e.b.BooleanModel on failed attempts. Successful exploitation may not log an exception. WAF rules matching XStream gadget class names in POST bodies can detect this.
STEP 04

HSQLDB writes JSP webshell to disk

The BasicDataSource.getConnection() call connects to an embedded HSQLDB instance with attacker-controlled initialization SQL. The SQL creates a table containing a JSP scriptlet, then uses the SCRIPT statement to serialize it to /webapps/ROOT/<random>.jspws. The .jspws extension routes directly to Apache Jasper without hitting TeamCity's JspController authentication filter, which only intercepts .jsp requests.
Conditions required:
  • TeamCity process has write access to its own webroot (standard installation)
Where this breaks in practice:
  • None — the TeamCity process always has write access to its Tomcat webroot
Detection/coverage: File integrity monitoring on the TeamCity webroot (/webapps/ROOT/) for unexpected .jspws files. EDR file-write telemetry on the TeamCity server process creating new files in the web directory.
STEP 05

Trigger webshell for arbitrary command execution

The attacker issues a GET request to http(s)://<target>/<random>.jspws. Jasper compiles and executes the JSP, which calls Runtime.getRuntime().exec() with the attacker's command. The command runs with the full privileges of the TeamCity server process. The Rapid7 PoC then deletes the .jspws file from disk to reduce forensic artifacts.
Conditions required:
  • HTTP access to the TeamCity web interface (same port as Step 1)
Where this breaks in practice:
  • None
Detection/coverage: Process execution telemetry: child processes spawned by the TeamCity Java process (e.g., cmd.exe, /bin/sh, whoami, curl). Network-level: unexpected outbound connections from the TeamCity server.
STEP 06

Post-exploitation: credential harvest and supply-chain pivot

With OS-level access, the attacker reads TeamCity's internal database, configuration files, and credential stores — including VCS root passwords, deployment tokens, cloud API keys, and artifact registry credentials. They can modify build configurations to inject backdoors into build artifacts, compromise downstream deployment pipelines, or pivot laterally using harvested credentials. This is the supply-chain detonation point.
Conditions required:
  • Successful RCE from Step 5
Where this breaks in practice:
  • Credential rotation and secrets management (e.g., HashiCorp Vault with short-lived tokens) limits the blast radius but does not prevent initial compromise
Detection/coverage: Anomalous TeamCity API calls or configuration changes. Credential usage from unexpected source IPs. Build artifact hash mismatches. SIEM correlation of TeamCity server process network activity.
03 · Compensating Control

1
CRITICAL 9.8→HIGH 7.5
SEVERITY REDUCED
Restrict network access to TeamCity to authorized build agents and administrators only — Place TeamCity behind a VPN, zero-trust gateway, or firewall ACL that limits inbound HTTP/HTTPS to known build agent IPs and administrator workstations. This breaks Step 1 of the attack chain by preventing unauthorized hosts from reaching the agent registration endpoint. Deploy within 3 days per the noisgate mitigation SLA for CRITICAL findings. This is the single most impactful control short of patching.
2
CRITICAL 9.8→HIGH 8.0
SEVERITY REDUCED
Deploy WAF rules blocking XStream gadget class names in POST bodies to /app/agents/v1/* — Configure your WAF or reverse proxy to inspect POST bodies to /app/agents/v1/commands/error and /app/agents/v1/register for known gadget class names (HSQLMetadataStorage, BooleanModel, TiedMapEntry, BasicDataSource). This disrupts Step 3 but can be bypassed by obfuscation. Deploy within 3 days.
3
CRITICAL 9.8→LOW 2.0
SEVERITY REDUCED
Install the JetBrains security patch plugin (for versions 2017.1+) — If you cannot immediately upgrade to 2025.11.7 or 2026.1.3, install the security patch plugin from JetBrains. It adds NoTypePermission.NONE before the allowlist, closing the deserialization gap. This directly fixes the root cause without a full version upgrade. Deploy within 3 days. Note: JetBrains recommends a full upgrade to receive all security fixes — the plugin addresses only CVE-2026-63077.
4
CRITICAL 9.8→CRITICAL 9.0
Enable file integrity monitoring on TeamCity webroot — Configure FIM or EDR to alert on any new .jspws, .jsp, or .war file creation in the TeamCity Tomcat webroot (/webapps/ROOT/ or equivalent). This detects Step 4 of the attack chain (webshell drop) and enables rapid incident response even if exploitation succeeds. Deploy within 3 days.
5
CRITICAL 9.8→CRITICAL 9.8
Rotate all credentials stored in or accessible to TeamCity — After patching or applying the security plugin, rotate all VCS root passwords, deployment tokens, cloud API keys, artifact registry credentials, and any other secrets stored in TeamCity. Assume compromise if the server was internet-facing and unpatched between July 27 and your patch date. Conduct forensic review of build logs and configurations for the disclosure window. Complete within 7 days of patching.
What doesn't work
  • EDR alone does not prevent exploitation — the attack writes a file and triggers a JSP compilation within the existing TeamCity Java process. Most EDR products will not block a legitimate Java process from writing to its own webroot. EDR may detect post-exploitation commands but will not stop the initial RCE.
  • Network segmentation without ACLs on the TeamCity port — segmenting TeamCity into a 'build' VLAN does not help if build agents (which are the intended clients) can still reach it, because the exploit uses the same protocol build agents use. The attacker only needs to compromise or impersonate one agent.
  • Disabling unused build agents — the vulnerability is in the server-side registration and error-command endpoints, not in agent behavior. Removing agents does not close the endpoint.
  • Upgrading XStream independently — the vulnerability is in TeamCity's usage of XStream (failure to reset default permissions), not in XStream itself. Replacing the XStream JAR does not fix the issue.
04 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationConfirmed. CISA added to KEV on 2026-08-05. Ransomware exploitation confirmed 2026-09-24. JetBrains confirmed reports of successful exploitation against internet-facing servers on 2026-08-07. Australian Signals Directorate (ASD/ACSC) reported exploitation against Australian TeamCity servers.
Proof-of-Concept AvailabilityWeaponized. Rapid7 (Stephen Fewer) published a full PoC Python script. GitHub repos 0xCyp1337/CVE-2026-63077 and AnggaTechI/CVE-2026-63077 provide mass-scanning, multi-threaded exploitation tools with interactive shells. 1 ExploitDB entry, 5+ GitHub PoC repos, 1 Nuclei template targeting /app/agents/v1 exist per pocindex.io.
EPSS Score0.8957 (89.57th percentile) — top 11% probability of exploitation in the next 30 days. One of the highest EPSS scores for any 2026 CVE.
CISA KEV StatusListed 2026-08-05. Federal remediation deadline was 2026-08-08 per BOD 26-04. Ransomware flag added 2026-09-24.
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H — Network-accessible, low complexity, no privileges, no user interaction, full CIA impact. This is the maximum-severity profile for an unchanged-scope vulnerability.
Affected VersionsAll TeamCity On-Premises versions prior to 2025.11.7 (LTS branch) and 2026.1.3 (current branch). TeamCity Cloud is not affected.
Fixed VersionsTeamCity 2025.11.7 and 2026.1.3. Security patch plugin available for versions 2017.1+ as an interim measure. Versions 2024.03+ auto-download the plugin and notify administrators.
Internet ExposureShadowserver tracked ~700 internet-facing unpatched TeamCity servers in early September 2026, declining to ~160 by late September. Historical Shodan data showed ~2,200-3,000 internet-exposed instances in prior years. JetBrains states 30,000+ DevOps teams use TeamCity (named customers: Citibank, Tesla, Amazon Games, Samsung).
Disclosure TimelineReported to JetBrains 2026-07-10. Patch released 2026-07-25. Advisory published 2026-07-27. Rapid7 analysis 2026-08-07. KEV listed 2026-08-05. Ransomware flag 2026-09-24.
Discovery CreditStephen Fewer, Rapid7 Labs. Root cause analysis and PoC published by Rapid7. Historical precedent: APT29/Midnight Blizzard mass-exploited CVE-2024-27198 (prior TeamCity auth bypass) for supply-chain access in late 2023.

Sources.

  1. JetBrains Security Advisory
  2. Rapid7 Technical Analysis
  3. Rapid7 Emergency Threat Response
  4. CISA KEV Catalog Addition
  5. The Hacker News — CISA Flags Active Exploitation
  6. JetBrains Post-Exploitation Update
  7. CSA Research Note — KEV Analysis
  8. Ransomware Exploitation Confirmation
05 · The Call

Final Verdict
= UNCHANGED to CRITICAL (9.8/10)

Why this verdict

  • Zero friction in the attack chain. Every step from registration to shell is unauthenticated, single-request, requires no user interaction, and has no race conditions or timing dependencies. The only prerequisite is HTTP access to the server — and TeamCity is commonly internet-facing for distributed build agents.
  • Weaponized exploitation is already happening. KEV-listed since August 5, ransomware-flagged since September 24, multiple turnkey exploit tools with mass-scanning on GitHub, a Nuclei template for automated detection, and confirmed exploitation against production servers in multiple countries. This is not a future risk — it is a present emergency.
  • Role multiplier: CI/CD platform is a canonical high-value-role component. 100% of TeamCity installations are CI/CD servers by definition. The blast radius is supply-chain-scale: compromising a TeamCity server yields stored VCS credentials, cloud deployment tokens, artifact registry keys, and the ability to inject backdoors into build artifacts consumed by downstream environments. A single compromised TeamCity server can pivot to every system that trusts its build output — production deployments, container registries, package repositories. This is not a workstation vulnerability that might occasionally land on a server; this IS the server. The verdict floor per the high-value-role rule is CRITICAL, and nothing in the friction analysis pushes it down.
  • EPSS 89.57th percentile confirms real-world exploitability. The statistical model independently rates this in the top 11% of all CVEs for exploitation probability, consistent with the observed weaponization and KEV listing.
  • Historical pattern: APT29 precedent. Russia's SVR exploited a prior TeamCity vulnerability (CVE-2024-27198) at mass scale for supply-chain access in 2023-2024. State-level actors treat CI/CD infrastructure as a strategic target, not just an opportunistic one.

Why not higher?

A 9.8 is the effective maximum for an unchanged-scope CVSS 3.1 vector with full CIA impact. The supply-chain blast radius arguably warrants a score above 10.0, but the CVSS framework caps at 10.0 and the changed-scope variant would only apply if the vulnerability directly compromised a different security authority (e.g., hypervisor escape). The real-world impact exceeds what CVSS can express, but 9.8 is the correct technical ceiling.

Why not lower?

Every friction-based downgrade argument fails here. *'Requires network access'* — TeamCity is designed to be reachable by distributed agents, and hundreds of instances remain internet-facing. *'Internal-only deployments are safer'* — true, but the component is a CI/CD server; any attacker with internal network access (phishing, VPN compromise, adjacent host) reaches it immediately, and post-compromise of a CI/CD server is catastrophic regardless of how the attacker got in. *'Patching is available'* — patch availability does not reduce severity, only urgency. The attack is trivial, weaponized, and actively exploited against a supply-chain-critical component class. There is no defensible argument for anything below CRITICAL.

06 · Verification

Crowdsourced verification payload.

Run this script on any host with curl and network access to the TeamCity server. No authentication required — it queries the unauthenticated server version endpoint. Invoke as: bash check_cve_2026_63077.sh https://teamcity.example.com:8111

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2026_63077.sh — Check JetBrains TeamCity for CVE-2026-63077
# Usage: bash check_cve_2026_63077.sh <TEAMCITY_BASE_URL>
# Example: bash check_cve_2026_63077.sh https://teamcity.example.com:8111
# Requires: curl, no authentication needed
# Exit codes: 1=VULNERABLE, 0=PATCHED, 2=UNKNOWN

set -euo pipefail

if [ $# -lt 1 ]; then
  echo "Usage: $0 <TEAMCITY_BASE_URL>"
  echo "Example: $0 https://teamcity.example.com:8111"
  exit 2
fi

BASE_URL="${1%/}"

# Fetch server version via REST API (unauthenticated endpoint)
VERSION_JSON=$(curl -sSf -k --max-time 10 "${BASE_URL}/app/rest/server" -H "Accept: application/json" 2>/dev/null) || {
  echo "UNKNOWN — Could not connect to TeamCity at ${BASE_URL}"
  exit 2
}

# Extract version and build number
VERSION=$(echo "$VERSION_JSON" | grep -oP '"version"\s*:\s*"\K[^"]+' 2>/dev/null || echo "")
BUILD=$(echo "$VERSION_JSON" | grep -oP '"buildNumber"\s*:\s*"\K[^"]+' 2>/dev/null || echo "")

if [ -z "$VERSION" ]; then
  echo "UNKNOWN — Could not parse TeamCity version from response"
  exit 2
fi

echo "Detected TeamCity version: ${VERSION} (build ${BUILD})"

# Parse major.minor.patch from version string
# Fixed versions: 2025.11.7 and 2026.1.3
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
PATCH=$(echo "$VERSION" | cut -d. -f3)

# Default patch to 0 if not present
PATCH=${PATCH:-0}

# Check if version is patched
if [ "$MAJOR" -gt 2026 ] 2>/dev/null; then
  echo "PATCHED — Version ${VERSION} is newer than all affected versions"
  exit 0
elif [ "$MAJOR" -eq 2026 ]; then
  if [ "$MINOR" -gt 1 ] 2>/dev/null; then
    echo "PATCHED — Version ${VERSION} is newer than fixed version 2026.1.3"
    exit 0
  elif [ "$MINOR" -eq 1 ] && [ "$PATCH" -ge 3 ] 2>/dev/null; then
    echo "PATCHED — Version ${VERSION} includes the fix (>= 2026.1.3)"
    exit 0
  else
    echo "VULNERABLE — Version ${VERSION} is affected by CVE-2026-63077 (needs >= 2026.1.3)"
    exit 1
  fi
elif [ "$MAJOR" -eq 2025 ]; then
  if [ "$MINOR" -gt 11 ] 2>/dev/null; then
    echo "PATCHED — Version ${VERSION} is newer than fixed version 2025.11.7"
    exit 0
  elif [ "$MINOR" -eq 11 ] && [ "$PATCH" -ge 7 ] 2>/dev/null; then
    echo "PATCHED — Version ${VERSION} includes the fix (>= 2025.11.7)"
    exit 0
  else
    echo "VULNERABLE — Version ${VERSION} is affected by CVE-2026-63077 (needs >= 2025.11.7)"
    exit 1
  fi
else
  # All versions prior to 2025.x are vulnerable
  echo "VULNERABLE — Version ${VERSION} is affected by CVE-2026-63077 (all versions before 2025.11.7 are vulnerable)"
  exit 1
fi