CVE-2023-34223

TeamCity's Open Diary: When Secrets Aren't Secret (CVE-2023-34223)

Alon Barad
Alon Barad
Software Engineer

Jan 10, 2026·6 min read

Executive Summary (TL;DR)

In TeamCity versions prior to 2023.05, the CI/CD server failed to apply input masking to 'password' type parameters when they were inherited from other builds (dependencies). This means that if Build B used a secret from Build A, that secret was printed in cleartext in Build B's logs. Any user with log-viewing permissions could scrape credentials, turning a 'Medium' severity bug into a potential critical infrastructure compromise.

A logic flaw in JetBrains TeamCity allowed password parameters sourced from build dependencies to be written to build logs in plain text, bypassing the standard masking mechanism.

The Hook: The CI/CD Paradox

CI/CD pipelines are the central nervous system of modern software engineering. They build our code, run our tests, and deploy our applications. To do this, they need access to everything: AWS keys, database credentials, SSH keys, and signing certificates. It is the one place in your infrastructure where God-mode privileges are aggregated.

Because of this, tools like JetBrains TeamCity have a sacred duty: Mask the secrets. When you define a variable as type password, the deal is simple: you type it in, TeamCity uses it, but in the logs, it shows up as ******. This allows developers to debug build failures without inadvertently seeing the production database password.

But what happens when the mechanism designed to hide these secrets gets confused? CVE-2023-34223 is exactly that scenario. It's the digital equivalent of whispering your ATM PIN into a megaphone because you thought the room was soundproof. It’s a vulnerability that turns your build logs—usually a boring scroll of compiler output—into a treasure map for attackers.

The Flaw: A Failure of Inheritance

To understand this bug, you have to understand TeamCity's Build Dependencies. In complex environments, builds are rarely isolated islands. You might have a 'Compile' build that passes artifacts to a 'Test' build, which triggers a 'Deploy' build. This chain requires data to flow downstream.

TeamCity allows you to reference parameters from upstream builds using a specific syntax: %dep.BuildID.parameterName%. This is incredibly useful. You define the API Key once in the root build, and everything downstream inherits it.

The flaw logic is painfully simple: TeamCity's logging engine knows how to mask parameters defined locally within a build configuration. It creates a 'deny-list' of strings to redact based on the current build's sensitive variables. However, in versions prior to 2023.05, this masking logic had a blind spot. It failed to correctly ingest the metadata for dependency parameters.

When the agent executed the build and resolved %dep.SourceBuild.SecretPassword%, the value was substituted into the command line or script correctly. But because the logger wasn't told, "Hey, this string coming from the dependency is also a secret," it treated the credential like any other string: Hello World. It wrote it straight to the disk, in plain text, for anyone with 'View Build Log' permissions to see.

The Code: Logic Reconstruction

While JetBrains keeps the specific source code close to their chest (and the fix is buried in a massive compiled JAR), we can reconstruct the logic failure based on the behavior. This is a classic issue of Context Propagation.

In a healthy masking implementation, the logic looks something like this:

// Pseudo-code of expected behavior
Set<String> secretsToMask = new HashSet<>();
 
// Add local parameters
secretsToMask.addAll(this.build.getPasswordParameters());
 
// Add dependency parameters (THE MISSING STEP)
for (Dependency dep : this.build.getDependencies()) {
    secretsToMask.addAll(dep.getPasswordParameters());
}
 
Logger.init(secretsToMask);

In CVE-2023-34223, the iteration over dependencies to extract their sensitive parameter definitions likely didn't happen, or the metadata regarding the type of the parameter (specifically password type) was lost during the variable resolution phase.

When the build agent runs a script:

# User script in TeamCity
echo "Deploying with key: %dep.AuthBuild.ApiKey%"

The variable resolver replaces %dep.AuthBuild.ApiKey% with super_secret_key_123. The logger receives the string Deploying with key: super_secret_key_123. It scans its secretsToMask list. Since the dependency key is missing from that list, the logger shrugs and writes the line to the persistent log file.

The Exploit: Reading the Diary

Exploiting this requires low privileges—specifically, access to view build logs. In many organizations, this permission is granted to every developer, QA engineer, and sometimes even project managers. The attack vector is essentially 'internal info disclosure'.

Here is how an insider threat or compromised developer account would capitalize on this:

1. Reconnaissance The attacker browses the project list looking for 'Deploy' or 'Release' configurations. These are the most likely to inherit credentials from a secure upstream configuration (like a 'Vault' or 'Secrets' build context).

2. The Setup The attacker finds a build chain: Build A (Secrets) -> Build B (Deployment). Build A has a hidden parameter env.AWS_SECRET_KEY type password.

3. The Trigger The attacker triggers Build B. If Build B has a step that blindly echoes variables or runs a command in verbose mode (e.g., bash -x or a tool that logs its arguments), the variable resolution kicks in.

4. The Loot The attacker simply opens the log tab for Build B, CTRL+F's for standard key formats (e.g., AKIA, ey..., -----BEGIN), and copies the credentials. No buffer overflows, no heap spraying, just reading.

The Impact: Why CVSS 4.3 is a Lie

The CVSS score of 4.3 (Medium) is technically correct based on the formula: it requires privileges (PR:L) and doesn't impact availability or integrity directly. Do not let this fool you.

In the real world, the impact of this vulnerability is often Critical.

Consider what lives in CI/CD variables:

  • Cloud Root Credentials: Full takeover of AWS/Azure/GCP accounts.
  • Signing Keys: Ability to sign malware as legitimate software.
  • Database Credentials: Full PII exfiltration.

While the vulnerability is medium severity, the exploit chain leads to total compromise. It turns your TeamCity server into a credential vending machine for anyone with a login. The 'Context' is Low integrity impact, but the 'Outcome' is a catastrophic data breach.

The Fix: Upgrade and Rotate

The remediation is straightforward but urgent.

1. Patch Immediately JetBrains fixed this in TeamCity version 2023.05. If you are running 2022.x or earlier, you are vulnerable. Upgrade the server. The agents will auto-upgrade upon connection.

2. The Clean Up (Crucial) Patching code stops future leaks. It does not fix past leaks. You must assume that any password parameter passed via dependency in previous builds has been compromised.

[!WARNING] Simply deleting the logs is not enough. If an attacker has already scraped them, the keys are in the wild.

3. Remediation Steps:

  • Identify all build configurations using %dep...% for password parameters.
  • Rotate every single one of those credentials. New API keys, new passwords, new certificates.
  • Audit the teamcity-server.log and access logs to see who accessed the build logs of sensitive deployment chains.

Technical Appendix

CVSS Score
4.3/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
EPSS Probability
0.00%
Top 100% most exploited

Affected Systems

JetBrains TeamCity < 2023.05

Affected Versions Detail

Product
Affected Versions
Fixed Version
TeamCity
JetBrains
< 2023.052023.05
AttributeDetail
CWE IDCWE-532 (Insertion of Sensitive Information into Log File)
CVSS v3.14.3 (Medium)
Attack VectorNetwork (Authenticated)
Privileges RequiredLow (View Log Permissions)
EPSS Score0.00004
ImpactInformation Disclosure (Credentials)
CWE-532
Insertion of Sensitive Information into Log File

Insertion of Sensitive Information into Log File

Vulnerability Timeline

CVE Published
2023-05-31
Patch Released (Version 2023.05)
2023-05-31

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.