fix: validate postMessage origin in LiveControls to prevent XSS#1581
fix: validate postMessage origin in LiveControls to prevent XSS#15810xcucumbersalad wants to merge 1 commit into
Conversation
Mirrors deco-cx/deco#1183. Adds a trusted-origin allowlist and message shape validation before dispatching `editor::inject`, which calls `eval` on attacker-controlled input. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe PR adds origin validation and runtime type-checking to the ChangesMessage Origin & Data Validation
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
Tagging OptionsShould a new tag be published when this PR is merged?
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@website/components/_Controls.tsx`:
- Around line 82-90: The handler assumes data.args.script exists when data.type
=== "editor::inject"; add a strict shape check before calling eval: ensure
data.args is an object and that (data.args as { script?: unknown }).script is a
string (and non-empty if desired), then only call eval(data.args.script). Update
the switch case for "editor::inject" to validate data.args and data.args.script
and return early if validation fails to avoid malformed-message crashes.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: df88efeb-dc19-48c6-bec6-a05ec7120c69
📒 Files selected for processing (1)
website/components/_Controls.tsx
| if ( | ||
| typeof data !== "object" || data === null || | ||
| typeof (data as { type?: unknown }).type !== "string" | ||
| ) { | ||
| return; | ||
| } | ||
| switch (data.type) { | ||
| case "editor::inject": { | ||
| return eval(data.args.script); |
There was a problem hiding this comment.
Validate args.script before eval to avoid malformed-message crashes.
Line 90 assumes data.args.script exists, but current guards only validate data.type. Add a strict check for the editor::inject payload shape before evaluating.
Proposed fix
- switch (data.type) {
- case "editor::inject": {
- return eval(data.args.script);
- }
- }
+ switch (data.type) {
+ case "editor::inject": {
+ if (
+ typeof (data as { args?: { script?: unknown } }).args?.script !== "string"
+ ) {
+ return;
+ }
+ return eval((data as { args: { script: string } }).args.script);
+ }
+ }🧰 Tools
🪛 Biome (2.4.14)
[error] 90-90: eval() exposes to security risks and performance issues.
(lint/security/noGlobalEval)
🪛 OpenGrep (1.20.0)
[ERROR] 90-90: eval() with dynamic input can execute arbitrary code. Avoid dynamic code evaluation entirely, or use a safe alternative.
(coderabbit.code-injection.eval-js)
🤖 Prompt for 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.
In `@website/components/_Controls.tsx` around lines 82 - 90, The handler assumes
data.args.script exists when data.type === "editor::inject"; add a strict shape
check before calling eval: ensure data.args is an object and that (data.args as
{ script?: unknown }).script is a string (and non-empty if desired), then only
call eval(data.args.script). Update the switch case for "editor::inject" to
validate data.args and data.args.script and return early if validation fails to
avoid malformed-message crashes.
There was a problem hiding this comment.
1 issue found across 1 file
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="website/components/_Controls.tsx">
<violation number="1" location="website/components/_Controls.tsx:83">
P2: Validate `args.script` before dispatching `editor::inject`; the current shape check still allows malformed messages to reach `data.args.script` and throw.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| typeof data !== "object" || data === null || | ||
| typeof (data as { type?: unknown }).type !== "string" | ||
| ) { |
There was a problem hiding this comment.
P2: Validate args.script before dispatching editor::inject; the current shape check still allows malformed messages to reach data.args.script and throw.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At website/components/_Controls.tsx, line 83:
<comment>Validate `args.script` before dispatching `editor::inject`; the current shape check still allows malformed messages to reach `data.args.script` and throw.</comment>
<file context>
@@ -59,8 +59,32 @@ const snippet = (live: Live) => {
+ }
const { data } = event;
+ if (
+ typeof data !== "object" || data === null ||
+ typeof (data as { type?: unknown }).type !== "string"
+ ) {
</file context>
| typeof data !== "object" || data === null || | |
| typeof (data as { type?: unknown }).type !== "string" | |
| ) { | |
| typeof data !== "object" || data === null || | |
| (data as { type?: unknown }).type !== "editor::inject" || | |
| typeof (data as { args?: { script?: unknown } }).args?.script !== "string" |
Mirrors deco-cx/deco#1183. Adds a trusted-origin allowlist and message shape validation before dispatching
editor::inject, which callsevalon attacker-controlled input.Summary by cubic
Validates postMessage origin and data shape in LiveControls to block XSS via
editor::inject. Adds a trusted-origin allowlist and guards soevalonly runs for trusted, well-formed messages.TRUSTED_ORIGINSallowlist (includes same-origin and*.deco.cx).typebefore handling.Written for commit ad09bed. Summary will update on new commits.
Summary by CodeRabbit