fix(editor): sanitize user name before CSS interpolation in Yjs awareness styles - #516
fix(editor): sanitize user name before CSS interpolation in Yjs awareness styles#516Xenon010101 wants to merge 2 commits into
Conversation
…ness styles The Yjs collaboration awareness handler interpolated state.user.name directly into a CSS string assigned via innerHTML. A collaborator with a crafted display name could break out of the CSS context and inject arbitrary HTML/JS into every other connected participant's browser. Add a sanitizeForCss helper that strips all characters except alphanumerics, spaces, hyphens, underscores, and dots before interpolation. Also replace innerHTML with textContent to prevent HTML parsing of the style content. Closes piyushdotcomm#515
👋 Thanks for opening a PR, @Xenon010101!Your PR has entered the 🚦 PR Review Pipeline.
What happens next
A pipeline status comment will appear below and update automatically as your PR progresses. While you wait
This comment is posted only once. |
|
Warning Review limit reached
Next review available in: 52 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
WalkthroughThe playground now sanitizes remote awareness user colors and names before embedding them in generated CSS, and applies the stylesheet through ChangesAwareness CSS safety
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related issues
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
PR Summary by QodoSanitize Yjs awareness user fields before CSS injection in PlaygroundEditor
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@modules/playground/components/playground-editor.tsx`:
- Around line 356-357: Update the color handling near the sanitized
state.user.color value to validate that it matches the supported six-digit
hexadecimal format before appending the alpha suffix; use the existing orange
fallback for invalid values, while leaving name sanitization unchanged.
- Around line 332-334: Update sanitizeForCss and the awareness value handling to
validate color and name as strings before sanitizing, and apply the fallback
when the sanitized result is empty. Ensure truthy non-string remote values
cannot reach string methods, covering both usages around the awareness rendering
logic.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: be1437e0-a4e2-4e6c-b4f5-78225376703a
📒 Files selected for processing (1)
modules/playground/components/playground-editor.tsx
Code Review by Qodo
Context used✅ Compliance rules (platform):
22 rules 1.
|
| .padEnd(6, "0") | ||
| : "#30bced"; | ||
|
|
||
| const sanitizeForCss = (value: string) => |
There was a problem hiding this comment.
2. Unicode names stripped 🐞 Bug ≡ Correctness
sanitizeForCss strips all characters outside an ASCII allowlist, so many legitimate OAuth display names (accented/CJK/Cyrillic/emoji) will be partially or fully removed before being rendered in the cursor label. This can result in empty or misleading collaborator labels in the editor.
Agent Prompt
### Issue description
The current regex-based sanitizer removes non-ASCII characters from display names, which can blank or truncate collaborator labels.
### Issue Context
The value is interpolated into a CSS `content: "${name}";` string.
### Fix Focus Areas
- modules/playground/components/playground-editor.tsx[332-373]
### Suggested fix
- Prefer escaping for a CSS string literal instead of stripping to ASCII:
- remove/escape control characters and newlines
- escape backslashes and double quotes (`\\` and `\"`)
- Keep the `textContent` assignment (good) and ensure the resulting string cannot terminate the quoted `content` literal.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Address review feedback: remote awareness data is not guaranteed to satisfy TypeScript types, so sanitizeForCss now accepts unknown and returns empty string for non-strings. Added sanitizeColor helper that validates 6-digit hex format before appending alpha suffix, falling back to #30bced for invalid values.
|
Addressed both review comments:
|
What changed
Sanitized the user display name before interpolating it into CSS in the Yjs awareness cursor styling, and replaced innerHTML with textContent on the injected style element.
Closes #515
Why
The Yjs collaboration awareness handler in playground-editor.tsx interpolated state.user.name directly into a CSS content property that was then assigned via styleEl.innerHTML. Since state.user.name originates from the user OAuth profile (e.g. Google display name), a malicious collaborator could set their name to break out of the style tag and inject arbitrary HTML/JS into every other connected participant browser. This is an XSS vulnerability in the real-time collaboration layer.
Fix
Verification