You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
WebCM currently passes an event payload to component listeners, but there is no public contract for fields that have been mapped from one source path into a component-specific destination path.
For tracking components, this architecture fails to reliably prevent PII exposure. A source field can be mapped into a destination-specific customer-information field, while the original plaintext source field remains in the payload and is later forwarded as generic event/custom data.
WebCM should support a per-component field-mapping consumption contract so mapped source fields containing PII can be removed before the component sends data to a tracking endpoint, or so mapping metadata is available to the component when it builds the outbound request.
Problem
The core problem is that WebCM has no place to represent "this source field has already been used to populate a component-specific destination field and must not be forwarded again as generic payload data."
That is a privacy boundary, not just a convenience feature. For analytics and advertising components, mapped destination fields often have special handling such as normalization, hashing, customer-data placement, consent handling, or provider-specific validation. If the original source field remains in the generic payload after mapping, the same PII value can be sent twice:
once through the intended destination-specific path,
again as plaintext custom/event data.
The current WebCM architecture makes that hard to prevent because:
As a result, a component can mutate the payload it receives, but it cannot know whether an arbitrary source field was already mapped into a destination field unless the manager removes that source field or passes mapping metadata. Without that contract, components that forward leftover payload data cannot distinguish intentional custom data from already-consumed PII source fields.
Concrete example: Facebook Pixel
The Facebook Pixel integration shows the failure mode clearly.
That behavior is correct when the incoming payload uses the exact Meta destination keys. The gap appears when a manager maps a custom source field into one of those destination keys but preserves the original source field in the payload. The component can hash/delete the destination key, but it has no way to know that the original source field was consumed by that mapping.
Failure mode:
mapped customer-information value is sent in the destination-specific field, for example Meta user_data
original plaintext source field remains in the component payload
original source field is eligible for generic event/custom data forwarding
the tracking service can receive both the hashed destination value and the original plaintext source value
The issue is not a specific field name. Source field names are customer-defined. A hard-coded denylist of common aliases cannot solve this reliably.
Proposed solution
Add a WebCM / Component Manager contract for component-specific payload projection and consumed source fields.
Preferred shape:
Preserve the original payload. Keep the request payload immutable.
Create a component-specific payload. Build a fresh payload for each component invocation.
Apply mappings in the manager. Resolve source paths into that component/action's destination fields.
Record consumed source paths. Mark mapped source paths as consumed when they populate destination-specific fields.
Exclude consumed fields from passthrough data. Remove consumed source paths before dispatch, or exclude them from any generic custom-data passthrough.
Dispatch only the projected payload. Invoke the component with the component-specific payload.
This keeps privacy-sensitive cleanup in the manager layer, where field mappings are known.
Alternative acceptable design
If manager-side removal is not the right abstraction, expose mapping metadata to the component, for example:
The component could then remove consumed source fields before building an outbound tracking-service request.
This is less robust than manager-side projection because every component must implement cleanup correctly, but it is still better than leaving components to guess source aliases.
Alternatives considered
Hard-coded PII/source-field denylists in individual components are incomplete because source field names are customer-defined.
Expecting each component manager to invent its own cleanup convention works only locally and does not establish an interoperable Managed Components contract.
Leaving cleanup to the destination component is not possible with the current public event contract unless the component also receives mapping metadata.
Impact
This affects any component manager or integration that:
lets users map source event properties into component-specific destination fields,
passes the original event payload through to the component, and
relies on the component to forward remaining payload keys as generic event/custom data.
For analytics and advertising components, the failure mode can expose plaintext customer-information source fields alongside normalized or hashed destination fields.
Prior-art search
Related but not duplicate:
Normalize event payloads #58 discussed normalizing event payload shapes, but did not address mapped-field consumption or source-field cleanup.
Custom events how to #68 discussed custom event payloads, but not component-specific mappings or consumed source fields.
Summary
WebCM currently passes an event payload to component listeners, but there is no public contract for fields that have been mapped from one source path into a component-specific destination path.
For tracking components, this architecture fails to reliably prevent PII exposure. A source field can be mapped into a destination-specific customer-information field, while the original plaintext source field remains in the payload and is later forwarded as generic event/custom data.
WebCM should support a per-component field-mapping consumption contract so mapped source fields containing PII can be removed before the component sends data to a tracking endpoint, or so mapping metadata is available to the component when it builds the outbound request.
Problem
The core problem is that WebCM has no place to represent "this source field has already been used to populate a component-specific destination field and must not be forwarded again as generic payload data."
That is a privacy boundary, not just a convenience feature. For analytics and advertising components, mapped destination fields often have special handling such as normalization, hashing, customer-data placement, consent handling, or provider-specific validation. If the original source field remains in the generic payload after mapping, the same PII value can be sent twice:
The current WebCM architecture makes that hard to prevent because:
MCEvent.payloadis created directly from the request body: https://github.com/cloudflare/webcm/blob/v0.10.9/src/manager.ts#L26-L37handleEventcreates anMCEventand dispatches it to registered listeners for each component: https://github.com/cloudflare/webcm/blob/v0.10.9/src/server.ts#L118-L147settingsandpermissions, but does not express field mappings, consumed source fields, custom-data allowlists, or payload projection rules: https://github.com/cloudflare/webcm/blob/v0.10.9/src/compConfig.ts#L3-L22ManagerAPI supports event listeners, client listeners, fetch/proxy/route/serve, cache, embeds, and widgets, but does not expose mapping metadata or a pre-dispatch payload transform hook: https://github.com/cloudflare/webcm/blob/v0.10.9/src/manager.ts#L386-L461As a result, a component can mutate the payload it receives, but it cannot know whether an arbitrary source field was already mapped into a destination field unless the manager removes that source field or passes mapping metadata. Without that contract, components that forward leftover payload data cannot distinguish intentional custom data from already-consumed PII source fields.
Concrete example: Facebook Pixel
The Facebook Pixel integration shows the failure mode clearly.
Current component behavior:
em,ph,fn,ln,ct,st,zp,country, andexternal_id: https://github.com/managed-components/facebook-pixel/blob/v1.0.13/src/track.ts#L4-L18body.user_data, and deletes those exact destination keys from the payload: https://github.com/managed-components/facebook-pixel/blob/v1.0.13/src/track.ts#L124-L138custom_data: https://github.com/managed-components/facebook-pixel/blob/v1.0.13/src/track.ts#L144-L144That behavior is correct when the incoming payload uses the exact Meta destination keys. The gap appears when a manager maps a custom source field into one of those destination keys but preserves the original source field in the payload. The component can hash/delete the destination key, but it has no way to know that the original source field was consumed by that mapping.
Failure mode:
user_dataThe issue is not a specific field name. Source field names are customer-defined. A hard-coded denylist of common aliases cannot solve this reliably.
Proposed solution
Add a WebCM / Component Manager contract for component-specific payload projection and consumed source fields.
Preferred shape:
This keeps privacy-sensitive cleanup in the manager layer, where field mappings are known.
Alternative acceptable design
If manager-side removal is not the right abstraction, expose mapping metadata to the component, for example:
The component could then remove consumed source fields before building an outbound tracking-service request.
This is less robust than manager-side projection because every component must implement cleanup correctly, but it is still better than leaving components to guess source aliases.
Alternatives considered
Hard-coded PII/source-field denylists in individual components are incomplete because source field names are customer-defined.
Expecting each component manager to invent its own cleanup convention works only locally and does not establish an interoperable Managed Components contract.
Leaving cleanup to the destination component is not possible with the current public event contract unless the component also receives mapping metadata.
Impact
This affects any component manager or integration that:
For analytics and advertising components, the failure mode can expose plaintext customer-information source fields alongside normalized or hashed destination fields.
Prior-art search
Related but not duplicate: