CVEReports
Reports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Reports
  • Sitemap

Company

  • About
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Powered by Google Gemini & CVE Feed

|
•

CVE-2025-14986
CVSS 1.3|EPSS 0.05%

The Old Switcheroo: Bypassing Namespace Policies in Temporal (CVE-2025-14986)

Alon Barad
Alon Barad
Software Engineer•December 30, 2025•5 min read
No Known ExploitNot in KEV

Executive Summary (TL;DR)

Temporal's frontend failed to cross-check the namespace of an internal 'embedded' request against the outer wrapper request. An attacker could wrap a `StartWorkflow` command claiming to be for 'Namespace B' (high limits) inside a request authorized for 'Namespace A' (low limits). The server validated against B but executed in A, effectively bypassing namespace-level constraints.

A logic flaw in Temporal's `ExecuteMultiOperation` API allowed authenticated users to execute workflows in one namespace while validating them against the policies of another. By embedding a request with a mismatched namespace ID, attackers could bypass rate limits and feature gates.

The Hook: The Atomic Batch

Temporal is the engine that keeps the internet's state machines running. It’s complex, powerful, and usually, pretty strict about who does what. Recently, Temporal introduced ExecuteMultiOperation—a power-user feature designed to execute multiple commands (like starting a workflow and sending a signal) in a single, atomic gRPC call. It’s a performance optimization for high-throughput systems that need to reduce round-trips.

But here’s the thing about batch operations: they introduce complexity in validation. When you hand the bouncer a stack of IDs for your group, does he check every single one against the guest list, or does he just glance at the top one and wave you all through?

In CVE-2025-14986, it turns out the bouncer was a bit confused. He was checking the ID of the person inside the trench coat, but letting the person wearing the trench coat into the club based on that ID. This created a fascinating logic gap where policy checks (rate limits, feature flags) were decoupled from execution targets.

The Flaw: A Tale of Two Namespaces

The vulnerability lies in the ExecuteMultiOperation API handler. This handler accepts a request object that wraps a list of operations. Crucially, the wrapper has a Namespace field (used for routing and authorization), and the embedded operations (like StartWorkflowExecutionRequest) also have their own Namespace fields.

Logic dictates that these should match. If I authenticate to Namespace-A, I shouldn't be able to submit an embedded command for Namespace-B. However, the code responsible for validating the request—checking if the namespace has enough rate limit quota remaining or if a specific beta feature is enabled—looked at the embedded namespace.

Meanwhile, the code responsible for executing the logic (creating the workflow row in the database) looked at the outer namespace.

This is a classic 'Object of Check vs. Object of Use' vulnerability. The system validated the rules for the decoy namespace but applied the effects to the target namespace.

The Code: The Missing Equality Check

Let's look at what the logic likely resembled before the fix. The handler iterates over the operations to perform pre-execution checks.

Vulnerable Logic (Conceptual):

func (h *Handler) ExecuteMultiOperation(ctx context.Context, req *workflow.ExecuteMultiOperationRequest) ... {
    // 1. Authorize against the OUTER namespace (Correct)
    if !h.authorize(ctx, req.Namespace) {
        return Error("Unauthorized")
    }
 
    // 2. Iterate over operations to validate limits/gates
    for _, op := range req.Operations {
        // BUG: Validating against the INNER namespace provided in the op!
        // If op.Namespace is "Enterprise-Tier", we get high limits.
        if !h.validateRateLimits(op.Namespace) {
             return Error("Rate limit exceeded")
        }
    }
 
    // 3. Execute in the OUTER namespace
    return h.engine.ExecuteMulti(ctx, req.Namespace, req.Operations)
}

Because the validateRateLimits function trusted the namespace string inside the operation struct, the attacker controlled the policy context completely independent of their execution context.

The Fix (PR #8839): The remediation was simple but critical: enforce that op.Namespace == req.Namespace.

for _, op := range req.Operations {
    if op.Namespace != req.Namespace {
        return Error("Namespace mismatch: Inner operation must match outer request")
    }
    // ... proceed with validation
}

The Exploit: Bypassing the Governor

To exploit this, we don't need memory corruption or complex heap spraying. We just need to speak gRPC. An attacker with access to a low-tier namespace (let's call it FreeTier-NS) wants to run a heavy workload that usually gets throttled.

They construct a ExecuteMultiOperationRequest:

  1. Outer Namespace: FreeTier-NS (Where they have valid credentials).
  2. Inner Operation: StartWorkflowExecutionRequest.
  3. Inner Namespace: Enterprise-NS (A namespace known to have high throughput limits or specific feature flags enabled).

The Attack Chain:

  1. The attacker sends this malformed packet to the Temporal frontend.
  2. The Frontend validates the auth token against FreeTier-NS. Pass.
  3. The Frontend checks rate limits. It sees the inner operation claims to be for Enterprise-NS. It checks the Enterprise-NS bucket. Pass (it has plenty of capacity).
  4. The Frontend executes the workflow. It uses the FreeTier-NS context from the outer wrapper.
  5. Success: The attacker has successfully started a workflow in their own namespace, bypassing the rate limits that should have stopped them.

The Impact: Why CVSS 1.3 is Deceptive

The CVSS score of 1.3 (Low) suggests this is barely a nuisance. And strictly speaking, from a CIA (Confidentiality, Integrity, Availability) triad perspective, it is minor. You cannot read data from other namespaces. You cannot write data to namespaces you don't own.

However, in a multi-tenant SaaS environment, Policy is Money.

If Temporal is being offered as a managed service, this bug allows a tenant on the $5/month plan to utilize the resources and throughput of the $5000/month plan. It breaks the business logic of tenancy isolation, even if it preserves the data integrity of tenancy. Furthermore, it allows bypassing Feature Gates. If a feature is disabled in your namespace because it's buggy or security-sensitive, you might be able to toggle it on by masquerading as a namespace that has it enabled.

Official Patches

TemporalPR #8839: Validate MultiOperation namespace match
TemporalTemporal v1.29.2 Release Notes

Technical Appendix

CVSS Score
1.3/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:U/S:N/AU:Y/R:U/RE:L/U:Green
EPSS Probability
0.05%
Top 88% most exploited

Affected Systems

Temporal Server 1.24.0Temporal Server 1.25.xTemporal Server 1.26.xTemporal Server 1.27.0 - 1.27.3Temporal Server 1.28.0 - 1.28.1Temporal Server 1.29.0 - 1.29.1

Affected Versions Detail

ProductAffected VersionsFixed Version
Temporal Server
Temporal Technologies
>= 1.24.0, < 1.27.41.27.4
Temporal Server
Temporal Technologies
>= 1.28.0, < 1.28.21.28.2
Temporal Server
Temporal Technologies
>= 1.29.0, < 1.29.21.29.2
AttributeDetail
CWECWE-863 (Incorrect Authorization)
CVSS v4.01.3 (Low)
VectorCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:N
Attack VectorNetwork (gRPC)
Exploit ComplexityLow
Privileges RequiredLow (Valid Namespace Access)

MITRE ATT&CK Mapping

MITRE ATT&CK Mapping

T1078Valid Accounts
Defense Evasion
T1562Impair Defenses
Defense Evasion
CWE-863
Incorrect Authorization

The software performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.

Exploit Resources

Known Exploits & Detection

Manual AnalysisExploitation requires constructing a gRPC request with mismatched namespaces using a custom client.

Vulnerability Timeline

Vulnerability Timeline

Vulnerability Disclosed/Patched in PR #8839
2025-02-01
Patch Released in v1.29.2
2025-02-05

References & Sources

  • [1]Temporal Security Advisories
  • [2]NVD - CVE-2025-14986

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.

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.