Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions website/components/_Controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,32 @@ const snippet = (live: Live) => {
globalThis.window.location.href = `${href}`;
}
};
const TRUSTED_ORIGINS = [
"https://deco.cx",
"https://admin.deco.cx",
"https://play.deco.cx",
"https://admin-cx.deco.page",
"https://deco.chat",
"https://admin.decocms.com",
"https://decocms.com",
"https://studio.decocms.com",
];
const isTrustedOrigin = (origin: string) =>
TRUSTED_ORIGINS.indexOf(origin) !== -1 ||
(origin.startsWith("https://") && origin.endsWith(".deco.cx")) ||
origin === globalThis.window.location.origin;

const onMessage = (event: MessageEvent<EditorEvent>) => {
if (!isTrustedOrigin(event.origin)) {
return;
}
const { data } = event;
if (
typeof data !== "object" || data === null ||
typeof (data as { type?: unknown }).type !== "string"
) {
Comment on lines +83 to +85

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Suggested change
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"

return;
}
switch (data.type) {
case "editor::inject": {
return eval(data.args.script);
Comment on lines +82 to 90

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

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.

Expand Down
Loading