feat: add value sanitization for UTM parameters#10
Conversation
Add a sanitization module that strips dangerous characters (HTML tags, control chars, custom patterns) from UTM parameter values at capture time to prevent XSS when values are rendered in HTML or used in URLs. - New SanitizeConfig type with enabled, stripHtml, stripControlChars, maxLength, and optional customPattern fields - sanitizeValue() and sanitizeParams() in src/core/sanitizer.ts - Integration into captureUtmParameters() pipeline (extract → filter → sanitize → convert key format) - Config system support: DEFAULT_SANITIZE_CONFIG, merge, validation - React hook forwards sanitize config to capture - Disabled by default with safe defaults when enabled - 266 tests passing (45 new) 🤖 Generated with [Nori](https://nori.ai) Co-Authored-By: Nori <contact@tilework.tech>
WalkthroughAdds configurable value sanitisation for UTM parameters (SanitizeConfig), implements sanitizer utilities, applies sanitisation during captureUtmParameters when enabled, exposes related types/exports, updates config merging/validation/defaults, and adds comprehensive tests and docs. Also adds Changes
Sequence Diagram(s)sequenceDiagram
actor Client
participant Hook as useUtmTracking
participant Capture as captureUtmParameters
participant Sanitiser as sanitizeParams
Client->>Hook: request capture with sanitize config
Hook->>Capture: call with URL params + sanitize option
Capture->>Capture: merge sanitize config with defaults
Capture->>Capture: filter by allowlist (if provided)
alt sanitize.enabled == true
Capture->>Sanitiser: sanitizeParams(params, config)
Sanitiser-->>Capture: return sanitised params
end
Capture->>Capture: convert keys to target keyFormat (e.g., camelCase)
Capture-->>Hook: return formatted params
Hook-->>Client: provide UTM parameters
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. No actionable comments were generated in the recent review. 🎉 Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/core/sanitizer.ts`:
- Around line 19-66: The functions ignore config.enabled; update sanitizeValue
and sanitizeParams to no-op when sanitization is disabled: in
sanitizeValue(value, config) return the original value immediately if
config.enabled === false, and in sanitizeParams(params, config) return params
unchanged (or a shallow copy of params) if config.enabled === false to avoid
mutating values when sanitisation is disabled; keep existing logic for the
enabled case and preserve references to sanitizeValue and sanitizeParams when
updating.
🧹 Nitpick comments (1)
src/core/docs.md (1)
43-45: Consider adjusting code span formatting to resolve linter warning.The static analysis tool flags spaces inside the code span on line 45. You could list each character in separate code spans for stricter compliance, though the current format is readable.
🔧 Optional fix for markdownlint warning
-- **sanitizer.ts**: `sanitizeValue()` strips dangerous characters from a single string value. Rules apply in order: HTML-significant characters (`< > " ' \``) --> control characters (\x00-\x1F except tab/newline/CR) --> optional custom regex pattern --> trim --> truncate to `maxLength`. `sanitizeParams()` applies `sanitizeValue()` to every non-undefined value in a `UtmParameters` object, returning a new object with keys preserved unchanged. Both functions are pure and stateless; all behavior is driven by the `SanitizeConfig` argument. +- **sanitizer.ts**: `sanitizeValue()` strips dangerous characters from a single string value. Rules apply in order: HTML-significant characters (`<`, `>`, `"`, `'`, `` ` ``) --> control characters (\x00-\x1F except tab/newline/CR) --> optional custom regex pattern --> trim --> truncate to `maxLength`. `sanitizeParams()` applies `sanitizeValue()` to every non-undefined value in a `UtmParameters` object, returning a new object with keys preserved unchanged. Both functions are pure and stateless; all behavior is driven by the `SanitizeConfig` argument.
Both functions are public API exports and should no-op when config.enabled is false, rather than relying on callers to check. 🤖 Generated with [Nori](https://nori.ai) Co-Authored-By: Nori <contact@tilework.tech>
Summary
🤖 Generated with Nori
src/core/sanitizer.ts) that strips HTML tags, control characters, and custom regex patterns from UTM parameter values at capture time to prevent XSSSanitizeConfigtype integrated into the config system withDEFAULT_SANITIZE_CONFIG(disabled by default, safe defaults when enabled)captureUtmParameters()pipeline and ReactuseUtmTrackinghook — acceptsPartial<SanitizeConfig>and merges with defaultscustomPatternmust be RegExp,maxLengthmust be positive finite number)Test Plan
sanitizeValueandsanitizeParams(HTML stripping, control chars, custom patterns, truncation, idempotency, edge cases)Share Nori with your team: https://www.npmjs.com/package/nori-ai
Summary by CodeRabbit
New Features
Documentation
Tests
Chores