[23] Pass an extra ApplicationBundleIdentifier through PCM
Severity: Low | Component: WebKit Networking / PCM | f8277ab
Rated Low because the diff is a feature addition rather than a vulnerability fix, but it relocates a privacy-proxy fail-closed flag from an unconditional set in the loader to a conditional set in a centralised helper and broadens the adattributiond daemon's sandbox/entitlements to permit direct network egress — two structural changes that narrow a privacy invariant and widen the daemon's attack surface.
Adds a "secondary" identifier (com.apple.webkit.adattributiond) plumbed through PrivateClickMeasurementManager and NetworkLoader::start, sets it on the NSURLSessionConfiguration for adattributiond's URLSession, and grants the daemon network-client/socket-delegate/networkserviceproxy entitlements plus mach-lookup for com.apple.networkserviceproxy. The _privacyProxyFailClosed flag moves from PrivateClickMeasurementNetworkLoaderCocoa.mm (unconditional) to NetworkDataTaskCocoa.mm::setPCMDataCarriedOnRequest next to _needsNetworkTrackingPrevention; per the commit message it now only applies outside debug mode.
Source/WebKit/NetworkProcess/PrivateClickMeasurement/cocoa/PrivateClickMeasurementNetworkLoaderCocoa.mm
WTF::switchOn(applicationBundleIdentifier,
- [&] (const String& bundleIdentifier) {
- configuration.get()._sourceApplicationBundleIdentifier = bundleIdentifier.createNSString().get();
+ [&] (const std::pair<String, String>& bundleIdentifiers) {
+ configuration.get()._sourceApplicationBundleIdentifier = bundleIdentifiers.first.createNSString().get();
+ configuration.get()._sourceApplicationSecondaryIdentifier = bundleIdentifiers.second.createNSString().get();
}, ...);
- [request _setPrivacyProxyFailClosed:YES];
+ [request setAttribution:NSURLRequestAttributionUser];
Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm
request._needsNetworkTrackingPrevention = YES;
+ request._privacyProxyFailClosed = YES;
Source/WebKit/Scripts/process-entitlements.sh
+ plistbuddy Add :com.apple.private.network.socket-delegate bool YES
+ plistbuddy Add :com.apple.security.network.client bool YES
+ plistbuddy Add :com.apple.private.networkserviceproxy bool YES
+ plistbuddy Add :com.apple.security.exception.mach-lookup.global-name:0 string com.apple.networkserviceproxy
Privacy-proxy fail-closed guard relocated and made conditional on debug mode, paired with a sandbox/entitlement relaxation that hands the attribution daemon a network egress path.
Patch Details
ApplicationBundleIdentifierOrAuditToken becomes ApplicationBundleIdentifiersOrAuditToken (Variant<std::pair<String, String>, Vector<uint8_t>>) and is threaded through PrivateClickMeasurementManager::create/ctor, NetworkLoader::start, managerOrProxy, and initializePCMStorageInDirectory. The Cocoa loader sets both _sourceApplicationBundleIdentifier and _sourceApplicationSecondaryIdentifier. PCMDaemonEntryPoint.mm hard-codes the secondary identifier to com.apple.webkit.adattributiond. setAttribution:NSURLRequestAttributionUser is now set on PCM report requests. The adattributiond sandbox profile is relaxed to read com.apple.networkextension.uuidcache.plist.
Background
PCM is WebKit's privacy-preserving ad-click attribution mechanism — a click on a source site stores metadata, and on later conversion an attribution report is sent to the source's endpoint. On iOS, PCM runs in an XPC daemon (adattributiond) using NSURLSession to post reports. _sourceApplicationBundleIdentifier/_sourceApplicationSecondaryIdentifier are NSURLSessionConfiguration SPIs that tag outgoing traffic with the originating application's identity. _privacyProxyFailClosed is an NSMutableURLRequest SPI that tells the networking stack to fail the request rather than fall back to a direct connection when the privacy relay is unavailable; without it, a relay outage degrades to a direct connection that exposes the client IP. networkserviceproxy is the system service that brokers network connections for sandboxed daemons.
Analysis
The refactor itself is mechanical and ownership-preserving — the Variant still holds either a value-pair of Strings or a Vector<uint8_t>, all by-value, so no lifetime change. The two behavioural deltas matter. The relocation of _privacyProxyFailClosed narrows the invariant from "set on this request object before it leaves the loader" to "set somewhere downstream conditional on PCM data being carried"; reviewers should be wary of any future code path that constructs a PCM-bound request but bypasses setPCMDataCarriedOnRequest, since the fail-closed guarantee would silently degrade.
Aaa Aaaaaaaaaaaaaa Aaaaaa Aaaaa a Aaaaaaaaaaaaaa Aaaaaaaaaa Aa Aaa Aaa Aaaaaaaaaa Aaaaa Aaa Aaaaaaaaa Aaaaaa Aaa Aaaaaa Aaa Aaaa Aaaaaa Aaaaaaa Aaa Aaaa Aa Aaaaaaaaaaaaaaaaaaaa Aaaaaaaaaa Aaaaaaa Aaa Aaa Aaaaaaaaa Aaaa Aaa Aaaaaa Aaaa Aaa Aaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaa Aaa Aaaaaa Aaaaaaaaaa Aaaaaaaaaa Aaa Aaaaaaaaaaaaaaaaa Aaaaa Aaaa Aaa Aaaaaaaaa Aaaaaaaaaa Aa Aaa Aaaa Aaaaa Aaaa Aaaaa Aaa Aaaa Aaa Aaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaaaaaa Aa Aaaaa Aaaaaaaaaaa Aaaaaaa Aa Aaaaaaaaaa Aaaaaaa Aaaaa Aa Aaaa Aaaaa Aaaaaaaa Aa Aaaaa Aaaaaaaaaaa Aaaaaa Aaaa Aa Aaaaaaaaaaaaaa Aaaaaa Aaaa Aaa Aaaaaa Aa Aaa Aaaaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaa Aaaaaaaaa Aa Aaaa Aa Aaaaaaaaaaa Aaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaaaaa Aa Aaa Aaaa Aaaaa
Aaaa Aaaaaaa Aaa Aaaaaaaaaaaaaa Aaaaaaaaaaa Aaaaa Aaaaaa Aaaa Aaa Aaaaaaaaa Aaaa Aaaaaaaa Aaaaa Aaaaaa Aaa Aaaaaaa Aaaaaa Aaaaaaa Aa Aaa Aaaaaaaaa Aaaaaaa Aaaaaaaa Aaa Aaaaaaaaaaa Aaaa Aa Aaaaaaa Aa Aaaaaa Aaaaaaaaaaaa Aaaaaaaaa Aa Aaaaaaaaaa Aa Aaaa Aaaaaa Aaaaaa
🔒The privacy-proxy and sandbox/entitlement implications of routing PCM traffic through a network-capable daemon are examined in depth.
Subscribe to read more
Audit directions
a Aaaaaaaaaaaaaaaaaa Aaaa Aaaaaaaaa Aaaa Aaaaaaaaaaaaaaaaaaaa Aa a Aaaaaaaaaaa Aaaaaaa Aaaaa Aaa Aaaaaa Aa Aaaaaaaaaaa Aa Aa Aaaaaaaa Aaaaaaaaaaaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaa Aaaaaa Aaaa Aaaaaa a Aaaaaaaaaaaa Aaaaaaa Aa Aaaaaaa Aaa Aaaaaaaaaaaaaaaa Aaaa Aaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaa a Aaaa Aa Aaa Aaaaaaaaaa Aaaaaa Aaaa Aaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
a Aaaaaaaa Aaaaaaaaaaaaaaaaaaa Aaaaaaaaaaa Aaaaaaaaaaa a Aaa Aaaaaaaaaa Aaaaaaaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaa Aaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaa Aaaaa Aaa Aaaaaaaaaaaa Aa Aaa Aaaaaa Aaaa Aa Aaaaaaa Aa Aaaaaaaaaaaaaaaaaaa Aaa Aa Aaaa Aaa Aaaaa Aaa Aaa Aaaaaa Aaaaa Aaa Aaaaaaaaaaaaaaa Aaaaaa Aaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaa Aaa Aaaaaa Aaa Aaaaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
a Aaaaaaaaaaa Aaaaa Aaaaaaa Aaaa Aaaaaaa a Aaaaaaaaaaaa Aaaaaaaaaaa Aaaa a Aaaaa Aaaaaaaaaaaaaa Aaaaa Aaa Aaaaaaaaaa a Aaaaaaaaaaaa Aaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaaaaaa Aaaaa Aaaaaaaa Aaaaaaa Aaaa Aaaaaaa Aaa Aaaaaaaa Aaa Aaaa Aaaaaaaaaaaa Aaaaaaaa Aaaaa Aaaa Aaa Aaaaaaaaaaaaaa Aaaaaaa
a Aaaaaaaaaaaa Aaaaaa Aaaaaa Aaaaaaaaaaa Aaaa Aa a Aaaaaaaaa Aaa Aaaaaaaaaa Aaaaaaa Aaaaaaaaa Aaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aa a Aaaaa Aaa Aaaaaa Aaaaaaaaaa Aaaaa Aaaaaaaaaa Aaa Aaaa Aaa Aaaaaaa a Aaaa Aaaaaaaaaa Aaaaaaa Aaaaaa Aaaa Aaa Aaaaaaa Aaaaaaaaaaa
🔒Multiple reusable audit patterns identified around flag-relocation, daemon entitlement expansion, and Variant-shape migrations, each with concrete starting points.
Subscribe to read more