✨ Add href and aria-label to composed_path_selector - #5002
Draft
LFBarreto wants to merge 7 commits into
Draft
Conversation
Add sanitized href and aria-label to the click action composed_path_selector. This helps identify the clicked element without exposing PII. The href value keeps only the origin and the path. The path removes segments that look like generated identifiers. The href value drops the query string and the hash. A non-http(s) href keeps only the scheme. The aria-label value follows the same privacy rules as action names. This feature is behind the composed_path_selector_attributes experimental flag. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
✅ All CI checks and tests passed. 🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: 3808b57 | Docs | View more details | Give us feedback! |
Bundles Sizes Evolution
|
Run Prettier to fix a formatting issue. Fix the e2e assertion to match CSS.escape output for spaces and slashes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add a preceding sibling in the test body so the link's nth-child position stays fixed. Without it, the async and npm CI test setups append an init script after </body>. Browsers reparent that script into <body> as a sibling, which changed the number of children and added an unexpected nth-child to the selector. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Change the href sanitization to keep the (deduplicated) query parameter names while still dropping their values. Parameter names are typically static field names, not user data, so keeping them makes the selector more useful without exposing what was in the query string. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Do not apply the privacy-level masking to href. Its own sanitization (dropping query values, the hash, and any non-http(s) payload) is already the intended protection for this attribute, regardless of the privacy level in effect. aria-label keeps the existing masking behavior. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fix bugs found by code review: - Exclude href and aria-label from the safe-attributes allowlist, so setting actionNameAttribute to either no longer leaks the raw, unsanitized value alongside the sanitized one. - Detect the href's non-http(s) scheme from the parsed URL instead of a regex on the raw string, so a leading whitespace or control character can no longer bypass the scheme-only shortcut and leak the full payload (an email address, a script...). - Mask aria-label at the hidden and ignore privacy levels too, not only mask and mask-unless-allowlisted, matching how session replay already handles them. - Compare the resolved origin against the current page's origin to decide whether to show it, instead of pattern-matching the raw href, so a backslash-led href cannot hide a real cross-origin navigation. - Decode a path segment before checking if it looks generated, so a percent-encoded non-ASCII segment (ex: an accented word) is not redacted by mistake. - Resolve an empty href to the current document instead of treating it as absent. Also extract the aria-label masking logic into a shared, exported maskAttributeIfNeeded in privacy.ts, and fix a test cleanup that used an inline delete instead of registerCleanupTask. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The backslash-led href test relied on old Chrome/Edge (BrowserStack legacy devices) resolving "\\evil.example/..." as a file: URL, unlike current browsers, which resolve it as http:. Replace it with a <base> element pointing to a different origin, which resolves consistently across browsers and still exercises the same origin-comparison code path. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
_dd.action.target.composed_path_selectorhelps identify the clicked element for auto-collected click actions, but it does not collecthreforaria-label. These two attributes make the selector more useful:hrefidentifies which link was clicked, andaria-labelidentifies icon-only controls that have no visible text.We add both attributes while keeping the field PII-safe. No JIRA ticket exists for this change yet.
Changes
getComposedPathSelectornow takes the RUM configuration instead of a single attribute name.hrefis reduced to the origin plus a path where generated-looking segments (segments with a digit) are replaced with?. The hash and any non-http(s) payload (mailto:,tel:,javascript:,data:, ...) are dropped. Query string values are dropped too, but the (deduplicated) parameter names are kept, since they are typically static field names rather than user data. This sanitization ishref's only protection — it is never masked by the privacy level,data-dd-privacy, orenablePrivacyForActionName.aria-labelgoes through the same masking pipeline as action names (enablePrivacyForActionName,defaultPrivacyLevel,data-dd-privacy,$DD_ALLOW).composed_path_selector_attributesexperimental flag, so we can validate cardinality and PII exposure before turning them on by default._dd.action.target.composed_path_selectorstays outsidebeforeSend's modifiable fields, so the field's format stays stable for anything parsing it downstream. The sanitization above is therefore the only protectionhrefhas, by design.See
getComposedPathSelector.tsfor the implementation.Test instructions
yarn test:unit --spec packages/browser-rum-core/src/domain/getComposedPathSelector.spec.ts --spec packages/browser-rum-core/src/domain/action/trackClickActions.spec.tsyarn test:e2e -g "composed path selector"yarn dev, addenableExperimentalFeatures: ['composed_path_selector_attributes']to the sandboxDD_RUM.init()call insandbox/index.html, click a link with a query string and an icon button with anaria-label, and confirm_dd.action.target.composed_path_selectoron the intake payload contains the sanitizedhref(origin, grouped path, query param names only, never masked) and thearia-label(masked according to the privacy level), with no raw query values or tokens.Checklist