Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in Network
DescriptionUse after free in Network
ComponentNetwork
Bug ClassUAF
Tracker513177826
Fix commit67439edde7cd (chromium/src) +7/-3
CISA KEVNot listed
CreditedGoogle
Disclosed2026-05-27

Files Changed

  • services/network/trust_tokens/trust_token_request_issuance_helper.cc
From 67439edde7cde0a229a10ed514935ff10c93820b Mon Sep 17 00:00:00 2001
From: Aykut Bulut <aykutb@chromium.org>
Date: Fri, 15 May 2026 08:53:46 -0700
Subject: [PATCH] [PST] Fix Use-After-Free in helper

This CL applies the patch proposed in crbug.com/513177826.

This CL fixes a potential Heap Use-After-Free (UAF) vulnerability in the
Network Service's Private State Token (PST) issuance logic.

In TrustTokenRequestIssuanceHelper::Finalize, ProcessIssuanceResponse was
being called before removing the Sec-Private-State-Token header. On the
empty-value path, ProcessIssuanceResponse can invoke the completion callback
synchronously. This callback can re-enter URLLoader and lead to its deletion
(and the deletion of the headers it owns). When control returns to Finalize,
the subsequent call to RemoveHeader accessed freed memory.

This CL fixes the issue by copying the header value, removing the header
from response_headers, and then calling ProcessIssuanceResponse.

Fixed: 513177826
Change-Id: Ice1d49fb63ff555bbff37db67715825a8cf13781
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7847785
Commit-Queue: Aykut Bulut <aykutb@chromium.org>
Reviewed-by: Charles Harrison <csharrison@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1631319}
---

diff --git a/services/network/trust_tokens/trust_token_request_issuance_helper.cc b/services/network/trust_tokens/trust_token_request_issuance_helper.cc
index c4413f1..a3eccf0 100644
--- a/services/network/trust_tokens/trust_token_request_issuance_helper.cc
+++ b/services/network/trust_tokens/trust_token_request_issuance_helper.cc
@@ -258,10 +258,14 @@
     return;
   }
 
-  ProcessIssuanceResponse(std::string(*header_value), std::move(done));
-  // Can only remove the header after the last user of `header_value`, since it
-  // holds a pointer to the kTrustTokensSecTrustTokenHeader header's value.
+  // Copy the header value out of |response_headers| and strip the header
+  // *before* calling ProcessIssuanceResponse(): on the empty-value path that
+  // call runs |done| synchronously, which may re-enter URLLoader and delete it
+  // (and |response_headers|, and |this|) before returning.
+  std::string issuance_response(*header_value);
   response_headers.RemoveHeader(kTrustTokensSecTrustTokenHeader);
+  ProcessIssuanceResponse(std::move(issuance_response), std::move(done));
+  // |this| and |response_headers| may have been deleted.
 }
 
 void TrustTokenRequestIssuanceHelper::ProcessIssuanceResponse(
Loading diff…

Original Bug Report

reported by vm...@google.com

Use-After-Free in Network Service via synchronous re-entrancy in Private State Tokens

Project Fortify, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports without the Chrome Security team. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.

Overview: A potential Use-After-Free (UAF) write vulnerability exists in the Network Service when processing Private State Token issuance responses. Synchronous re-entrancy during response finalization can lead to the destruction of the URLLoader and its headers while they are still being accessed. This could allow a malicious issuer to trigger memory corruption in the sandboxed Network Service process.

Affected files:

  • services/network/trust_tokens/trust_token_request_issuance_helper.cc
  • services/network/url_loader.cc
  • net/http/http_response_headers.cc

Estimated timestamp from git blame: 2024-10-08

Description

A potential Heap Use-After-Free (UAF) vulnerability with a write primitive has been identified in the Network Service’s Private State Token (PST) issuance logic. The issue arises from a synchronous re-entrancy path in TrustTokenRequestIssuanceHelper::Finalize that allows the underlying URLLoader and its associated HttpResponseHeaders object to be destroyed before the helper completes its execution.

Technical Details

In services/network/trust_tokens/trust_token_request_issuance_helper.cc, the Finalize method processes the Sec-Private-State-Token response header. If this header is present but empty, the code executes a synchronous path:

// services/network/trust_tokens/trust_token_request_issuance_helper.cc
void TrustTokenRequestIssuanceHelper::Finalize(
    net::HttpResponseHeaders& response_headers,
    base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done) {
  ...
  ProcessIssuanceResponse(std::string(*header_value), std::move(done));
  // ...
  response_headers.RemoveHeader(kTrustTokensSecTrustTokenHeader); // POTENTIAL UAF
}

When the header value is empty, ProcessIssuanceResponse immediately invokes the done completion callback synchronously. This callback chain propagates back to the URLLoader, which continues its response processing. If the response contains certain headers (e.g., Ad-Auction-Only: true in a non-trusted request or a CORP violation), the URLLoader may call DeleteSelf() synchronously.

Because the URLLoader (and its net::URLRequest) owns the net::HttpResponseHeaders object via scoped_refptr, the synchronous deletion of the loader results in the destruction of the headers. When the stack unwinds back to the Finalize method, the subsequent call to response_headers.RemoveHeader accesses a deallocated object. This call leads to MergeWithHeaders and Parse, which perform multiple writes to the freed memory.

Potential Impact

If exploitable, this would allow deterministic memory corruption (UAF write) within the sandboxed Network Service process. The vulnerability is not protected by MiraclePtr because the dangling reference is held as a C++ reference on the stack during the re-entrant call, not as a raw_ptr member.

Suggested Reproduction Steps (Potential)

An attacker might attempt to trigger this via the following steps:

  1. Host a page that initiates a PST issuance request: fetch(url, {privateToken:{version:1, operation:'token-request'}}).
  2. The target origin must be a registered PST issuer controlled by the attacker.
  3. The issuer returns a response with:
    • Sec-Private-State-Token: (header present with an empty value)
    • Ad-Auction-Only: true (to trigger the synchronous DeleteSelf path in URLLoader for a renderer-initiated request).
  4. In a build with ASAN, this is expected to trigger a heap-use-after-free report in net::HttpResponseHeaders::RemoveHeader.

Ensure that the header removal occurs before the potentially synchronous ProcessIssuanceResponse call, or ensure that the completion callback is always invoked asynchronously (e.g., via base::SequencedTaskRunner::GetCurrentDefault()->PostTask) to prevent re-entrancy into the URLLoader while the helper is still using the headers reference.

Evaluated with Chrome root at commit: b3153093eb3c78c3e88ccf562bcbc20437a04b0e


Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:

  • If you are familiar with the severity guidelines, you may adjust the severity.
  • If this is a false positive, and there’s no work to be done, please close as WAI.
  • If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.

Data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.

View on issue tracker