Jul 29, 2026·5 min read·6 visits
Flaws in the OpenTelemetry JFlex SQL sanitizer allowed unredacted database credentials to leak into trace spans when using double quotes or executing multi-statement queries.
A sensitive data exposure vulnerability (CWE-532) exists in OpenTelemetry Java Instrumentation prior to version 2.28.0. The JDBC auto-instrumentation component's SQL statement sanitizer contains lexer flaws that prevent the correct redaction of administrative passwords under specific conditions, such as when double-quotes represent identifiers or during multi-statement executions separated by semicolons.
The OpenTelemetry Java Agent auto-instruments JDBC calls to capture execution statistics and structural database statement properties. To ensure privacy compliance and prevent credential leakage, the agent uses a JFlex-generated SQL scanner to sanitize incoming statements. This mechanism replaces raw literals with query parameter placeholders while retaining identifiers such as table and column names to provide telemetry context.
Prior to version 2.28.0, the SQL sanitizer failed to redact credentials under specific edge cases. Specifically, administrative commands that format credentials in unquoted or double-quoted blocks bypassed sanitization filters. This behavior allowed plaintext database passwords to leak into trace span attributes, such as db.statement, where they were subsequently exported to downstream APM collectors and monitoring backends.
The underlying vulnerability consists of two structural bugs in the JFlex-generated sanitizer states (SqlSanitizer.jflex and SqlSanitizerWithSummary.jflex).
The first bug involves the processing of double-quoted values. When the SQL sanitizer operates with the configuration flag doubleQuotesAreIdentifiers enabled, double-quoted tokens are evaluated as database identifiers instead of string literals. In database administrative operations, such as CREATE USER app_user PASSWORD "Secret123", the lexer classifies the password block as an identifier. Because identifiers are kept in clear-text to preserve schema tracking context, the password bypasses redaction filters.
The second bug is a state-tracking failure in multi-statement query batches. When the agent receives a multi-query batch separated by semicolons, such as SELECT 1; CONNECT user PASSWORD "secret", the state machine evaluates the first statement and transitions its internal operation tracker to a active query state (e.g., Select). Because the previous lexer implementation lacked an explicit state-reset transition rule upon encountering a semicolon, the operation variable remained set to Select rather than reverting to NoOp.INSTANCE. Consequently, when parsing the subsequent administrative command, the lexer did not execute keyword matching rules reserved for a fresh parser state, leaving the database credentials unredacted.
An examination of the original SqlSanitizer.jflex configuration reveals that the parser attempted to handle administrative statement truncation based solely on initial keyword state matching. This approach was highly fragile and failed to clear state boundaries correctly.
The patch implemented in commit 7ac7fa6fda6c2e3b65bc5d3c6eba050311a49511 addresses these issues by introducing structural state variables and an explicit semicolon reset rule:
private boolean statementStart = true;
private boolean passwordSanitizationEnabled = false;
private boolean identifiedBySanitizationEnabled = false;To correct the multi-statement boundary bug, a dedicated transition rule for semicolons was added to re-initialize the scanner's tracking states between statements within a single query execution block:
";" {
if (!insideComment) {
statementStart = true;
passwordSanitizationEnabled = false;
identifiedBySanitizationEnabled = false;
}
appendCurrentFragment();
if (isOverLimit()) return YYEOF;
}Additionally, the patch deprecates early-exit statement truncation on raw keywords like CONNECT or USER. Instead, matching these keywords sets tracking flags that indicate password sanitization is required. When the parser encounters explicit PASSWORD or IDENTIFIED BY tokens, it checks these flags and applies immediate replacement regardless of quoting style:
"PASSWORD" {
boolean passwordTokenIsIdentifier = false;
if (!insideComment && !extractionDone) {
markStatementStarted();
passwordTokenIsIdentifier = operation.handleIdentifier();
extractionDone = passwordTokenIsIdentifier;
}
appendCurrentFragment();
if (!passwordTokenIsIdentifier && !insideComment && shouldSanitizeRemainderAfterPassword()) {
builder.append(" ?");
return YYEOF;
}
if (isOverLimit()) return YYEOF;
}Triggering this vulnerability does not require an active exploit script. Rather, standard operations executing multi-statement or double-quoted credential administration commands under an instrumented JVM environment trigger the bug.
Consider an administrative microservice running with an OpenTelemetry Java Agent (< 2.28.0) that executes the following database query via JDBC:
SELECT 1; CONNECT admin PASSWORD "MySecr3tP@ss"Because of the semicolon state-retention bug, the parser evaluates the entire command stream under the initial Select context. The lexer ignores the CONNECT keyword and skips password redaction. The resulting span is recorded and exported with the plaintext password embedded directly inside the db.statement attribute:
{
"traceId": "9f0862089cba8c07e0b57e79c947ff1a",
"attributes": {
"db.system": "hana",
"db.statement": "SELECT ?; CONNECT admin PASSWORD \"MySecr3tP@ss\""
}
}Once exported, the credentials reside in clear-text in downstream telemetry databases (e.g., Elasticsearch, Tempo, or Jaeger), exposing administrative passwords to users with trace-viewing privileges.
The exposure of database administrative passwords in centralized telemetry databases poses a serious threat to enterprise security. Monitoring, logging, and tracing pipelines are often configured with broader access permissions and lower threat-protection controls than production databases.
An attacker who gains unauthorized access to log aggregators or APM dashboard search utilities can easily harvest administrative database credentials by searching for keywords like PASSWORD or IDENTIFIED BY. These credentials can then be used to perform unauthorized operations, exfiltrate business data, or gain initial lateral entry into target network environments.
While the direct CVSS 3.1 score is evaluated at 6.5 (Medium) due to the lack of immediate write or denial-of-service capability on the host, the downstream exploitation potential of exposed administrative credentials warrants swift remediation.
The primary remediation strategy is to upgrade the OpenTelemetry Java Agent and its associated dependencies to version 2.28.0 or higher. This upgrade updates the JFlex scanner definitions to enforce correct state transitions and robustly redact password literals.
For environments where immediate upgrades are not feasible, the following defense-in-depth mitigations should be enforced:
Enforce Parameterization: Avoid executing raw query strings that contain inline passwords. Migrate all user provisioning or connections to parameterized stored procedures or execution APIs.
Disable Multi-Query Processing: Configure JDBC connection profiles to reject multi-statement executions, ensuring that queries are parsed individually and do not bypass state boundaries.
Ingestion Filtering: Deploy processing rules on the OpenTelemetry Collector (or intermediate log stashes) to scrub any plain-text parameters matching password keywords before storage.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
opentelemetry-java-instrumentation OpenTelemetry | < 2.28.0 | 2.28.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-532 |
| Attack Vector | Network |
| CVSS Score | 6.5 |
| EPSS Score | 0.00224 |
| Impact | Sensitive Data Exposure |
| Exploit Status | Proof of Concept (PoC) documented |
| KEV Status | Not in CISA KEV |
The product writes sensitive information to log files, making it available to attackers who have access to the log repository.
CVE-2026-66066 (popularly known as 'KindaRails2Shell') is a critical security vulnerability in the Active Storage component of Ruby on Rails. The vulnerability arises from an insecure default integration with the libvips image processing library via the ruby-vips gem. Under default configurations, Active Storage fails to restrict untrusted format loaders within libvips, allowing remote, unauthenticated attackers to upload malformed files that leverage external dataset features to read local server files. By extracting cryptographic secrets such as SECRET_KEY_BASE from the leaked file contents, attackers can forge signed Marshal serialization payloads to achieve remote code execution.
An SSRF validation bypass exists in dssrf-js (v1.0.3 and prior) due to an improper string normalization sequence inside is_url_safe. Before validating the host using Node's WHATWG parser, the helper strips the '@' symbol. This corrupts the parser's authority resolution, while the application's client requests the original, un-sanitized string containing internal IP targets.
A Use-After-Free (UAF) vulnerability exists in msgpack-ruby prior to version 1.8.2. The MessagePack::Buffer#clear method returns the associated 4 KiB rmem page to the shared pool but fails to reset the buffer's tracking pointers (rmem_last, rmem_end, and rmem_owner). Subsequent write operations on the cleared buffer can alias the freed page, allowing concurrent buffers to access, disclose, or corrupt cross-buffer data. This issue is resolved in version 1.8.2.
Flyto2 Core (flyto-core) prior to version 2.26.7 did not utilize its centralized SSRF validation mechanism ('validate_url_with_env_config') across multiple HTTP-emitting modules. This oversight allowed low-privileged users executing automated workflows to perform Server-Side Request Forgery (SSRF) attacks against internal endpoints, loopback interfaces, and cloud provider metadata services.
An SSRF vulnerability exists in Flyto2 Core due to improper validation of intermediate HTTP redirect hops. While the initial request target is validated against an SSRF protection policy, the HTTP client library (aiohttp) transparently follows 30x redirects to local, internal, or cloud metadata endpoints without application-level revalidation.
A logic vulnerability exists in @dynatrace-oss/dynatrace-mcp-server prior to version 1.8.7. The create_dynatrace_notebook tool lacks a human-approval gate, allowing an attacker to exploit indirect prompt injection to force the underlying LLM client to create persistent Dynatrace notebooks without the operator's consent.