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



GHSA-28XX-PPPM-VQFF
7.5

GHSA-28xx-pppm-vqff: Silent Data Loss via Uncommitted Transactions in ydb-go-sdk

Amit Schendel
Amit Schendel
Senior Security Researcher

Apr 30, 2026·8 min read·4 visits

PoC Available

Executive Summary (TL;DR)

A logic bug in ydb-go-sdk overwrites the transaction control configuration, ignoring the WithCommit() flag. This causes transactions to remain uncommitted on the database server while the application assumes they succeeded, resulting in silent data loss.

The `ydb-go-sdk` for Yandex Database suffers from a critical logic vulnerability where transactions are not committed when using the `options.WithCommit()` option on the final `table.Transaction.Execute` call. This implementation flaw forces the SDK to discard the commit instruction before transmission. Consequently, the server processes the query but leaves the transaction open, while the SDK erroneously reports success to the calling application, leading to complete and silent data loss.

Vulnerability Overview

The ydb-go-sdk package serves as the primary Go client for Yandex Database (YDB). It provides high-level abstractions for managing database transactions and querying data across distributed systems. Developers rely on these structural abstractions to ensure database operations comply with strict ACID properties. The package includes an options.WithCommit() functional option designed to streamline transaction lifecycle management.

This specific flag instructs the SDK to finalize the transaction immediately upon the successful execution of the associated data query. Developers utilize this option on the final table.Transaction.Execute call to optimize performance by reducing network round trips to the backend database. The vulnerability arises when the SDK internally discards this crucial commit instruction immediately before constructing the final gRPC transmission.

Consequently, the YDB server processes the submitted data query but leaves the transaction in an open, uncommitted state due to the missing protocol flag. The SDK incorrectly interprets the successful query execution as a successful commit and returns a nil error to the calling application. The application code proceeds forward under the false assumption that the underlying database state is persistently modified.

The database server eventually terminates the idle transaction or issues a rollback command when the parent session explicitly closes. This sequence represents a complete failure of data durability and results in irreversible, silent data loss. The lack of explicit error propagation or panic conditions makes the issue particularly insidious for production environments monitoring standard error metrics.

Root Cause Analysis

The root cause of this vulnerability lies in a logic implementation error within the internal/table package of the ydb-go-sdk. The SDK initiates the construction of a gRPC ExecuteDataQueryRequest whenever a developer invokes the table.Transaction.Execute routine. The options.WithCommit() option is explicitly designed to modify this request by asserting a commit_tx boolean property within the transaction control structure.

The vulnerability occurs in the tableClientExecutor.execute method, which is physically located within the internal/table/session.go source file. This specific method acts as the final preparation stage, responsible for assembling the complete gRPC payload before dispatching it over the network. The implementation correctly applies the WithCommit parameter during the initial phase of request construction.

However, the execution method later performs an explicit and destructive overwrite of the request.TxControl field. It replaces the existing configuration with a locally cached txControl object derived strictly from the initial state of the parent transaction. This statically cached object does not incorporate the commit_tx instruction that was dynamically applied by the options.WithCommit() call option.

This late-stage assignment acts as a silent data-clobbering operation that effectively erases the developer's explicit intent to finalize the transaction. The resulting gRPC payload transmitted to the YDB backend lacks the necessary protocol flags to trigger the commit sequence. The database processes the query instruction precisely as formatted, executing the operation within the isolated transaction scope but deferring finalization indefinitely.

Code Analysis

The vulnerable code path involves an explicit struct field assignment operation that ignores previously applied functional call options. The tableClientExecutor.execute function accepts the generated Ydb_Table.ExecuteDataQueryRequest object alongside an array of grpc.CallOption variadic arguments. The implementation retrieves the initial transaction control state and attempts to blindly enforce it on the outgoing request.

func (e tableClientExecutor) execute(
    ctx context.Context,
    _ *tx.Control,
    request *Ydb_Table.ExecuteDataQueryRequest,
    callOptions ...grpc.CallOption,
) (*transaction, result.Result, error) {
    request.TxControl = txControl.ToYdbTableTransactionControl() // Vulnerable overwrite
    r, err := executeDataQuery(ctx, e.client, request, callOptions...)
    // ...
}

The targeted patch implemented in commit 25dcff4c41153f1f9413512ba12999b40bf7154d remediates this logic flaw by entirely removing the destructive assignment statement. By deleting request.TxControl = txControl.ToYdbTableTransactionControl(), the execution method successfully preserves the state mutations introduced by the options.WithCommit() functional parameter. The outgoing request subsequently retains the correct commit_tx boolean value required by the gRPC definition.

Prior to the direct fix, the developers introduced a significant architectural refactoring in commit 251128a64763555d9a79ee7a131dd154c9000eb9. This earlier commit centralized the transaction control parsing logic for both the Table and Query services, shifting the implementation into a unified internal/tx package. This structural consolidation reduced the overall bug surface area by enforcing a single, authoritative mechanism for mapping SDK abstraction options to low-level gRPC messages.

Exploitation Mechanism

Exploitation of this vulnerability does not require malicious external input, authentication bypasses, or specialized network positioning. The issue manifests organically through standard, documented application logic utilizing the official SDK components. Any application code utilizing the WithCommit() option on the final execution step natively triggers the vulnerability sequence.

A system service initiates a standard database interaction intending to modify operational state, such as updating a financial ledger or processing an inventory adjustment. The service initializes the transaction successfully and issues preliminary data validation queries. The final update query is then dispatched using the options.WithCommit() functional option to finalize the data state.

The application service receives a standard nil error response from the SDK client and subsequently logs a successful state modification operation. The system proceeds to acknowledge the completed transaction to the end-user or dispatch completion events to downstream microservices. At this exact moment, the operational state diverges completely from the underlying database state.

The backend database continues to maintain an uncommitted transaction referencing the isolated data updates. When the client session eventually terminates or the transaction idle timeout threshold is reached, the YDB server automatically rolls back all pending changes to enforce consistency. The downstream distributed systems process the logical operation while the physical data remains completely unmodified, leading to irreconcilable system state discrepancies.

Impact Assessment

The primary operational impact of this vulnerability is the absolute failure of data durability and atomicity guarantees. Applications built upon transactional databases inherently assume that successfully acknowledged changes remain persistent across service restarts and physical system failures. This implementation flaw silently nullifies that foundational assumption across all affected transactions.

Financial infrastructure, healthcare record processing, and access control management software are disproportionately threatened by this specific failure condition. A user might successfully finalize a transaction that deducts available funds from a ledger account, receive synchronous confirmation, and discover retroactively that the balance never actually modified. The backend database retains the unmodified account balance, while application monitoring metrics reflect a completed deduction.

Silent persistence failures represent a fundamentally higher severity risk profile than explicit application crashes or connection resets. An unhandled exception or a direct database error code immediately triggers telemetry alerts, prompting engineering investigation and automated retry execution. This vulnerability completely bypasses standard error propagation mechanics, allowing data inconsistencies to accumulate silently and scale across distributed services.

The statistical risk increases linearly alongside the application's overall transaction volume and engineering reliance on the WithCommit() optimization pattern. High-throughput distributed systems attempting to aggressively optimize database network latency are severely affected. The complete absence of standard exploitation artifacts or database-level error logging drastically complicates incident response procedures and historical data forensics.

Mitigation and Remediation

The definitive remediation strategy requires updating the ydb-go-sdk package dependency to a fully patched version. Version v3.134.2 introduces the complete sequence fix that explicitly prevents transaction control parameters from being erroneously overwritten during request compilation. Security teams must mandate this version constraint across all internal Go microservices, monolithic applications, and distributed processing agents utilizing Yandex Database.

In operational environments where an immediate dependency upgrade is prevented by organizational change freezes or compatibility issues, developers must implement a mandatory code-level workaround. Engineering teams must statically audit their codebases to identify all functional instances of table.Transaction.Execute utilizing the options.WithCommit() argument. Developers must physically remove this option parameter from the execution call signature.

To safely finalize transactions while maintaining the vulnerable SDK version, engineers must introduce an explicit invocation of tx.CommitTx(ctx) immediately following the final query execution. This modification necessitates an additional network round trip to the database backend but definitively guarantees the transaction state is communicated correctly. This structural workaround completely circumvents the vulnerable control logic overwrite within the execution pipeline.

// Vulnerable Implementation Pattern
_, err := tx.Execute(ctx, query, params, options.WithCommit())
if err != nil { return err }
 
// Remediated Workaround Pattern
_, err := tx.Execute(ctx, query, params)
if err != nil { return err }
err = tx.CommitTx(ctx)
if err != nil { return err }

Official Patches

YandexRelease v3.134.2
YandexDirect patch commit removing destructive assignment.

Fix Analysis (2)

Technical Appendix

CVSS Score
7.5/ 10

Affected Systems

ydb-go-sdk (github.com/ydb-platform/ydb-go-sdk)

Affected Versions Detail

Product
Affected Versions
Fixed Version
ydb-go-sdk
Yandex
< 3.134.23.134.2
AttributeDetail
CWE IDCWE-684: Incorrect Provision of Specified Functionality
Attack VectorLocal / Application Code Integration
ImpactSilent Data Loss, Atomicity Failure
Exploit Statusweaponized
Authentication RequiredNone

MITRE ATT&CK Mapping

T1565Data Manipulation
Impact
T1485Data Destruction
Impact
CWE-684
Incorrect Provision of Specified Functionality

The software does not properly implement the functionality defined by the API specification, leading to silent operational failure.

Known Exploits & Detection

GitHub Advisory DatabaseAdvisory describing the logic implementation error natively triggered by application code usage.

Vulnerability Timeline

Refactoring of transaction control logic (v3.104.6).
2024-03-23
Final fix for table.Session.Execute ignoring WithCommit committed.
2024-04-22
Version v3.134.2 released.
2024-04-22

References & Sources

  • [1]GHSA-28xx-pppm-vqff Advisory
  • [2]Commit 251128a64763555d9a79ee7a131dd154c9000eb9
  • [3]Commit 25dcff4c41153f1f9413512ba12999b40bf7154d
  • [4]Release v3.134.2

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.