You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2026/06/01 22:26:18 UTC
(superset) 01/01: fix(embedded-sdk): validate embedded dashboard id format before use
This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch fix/embedded-sdk-id-format-validation
in repository https://gitbox.apache.org/repos/asf/superset.git
commit 4f2fe420444220b0dd316aee91d652e144786f31
Author: Claude Code <no...@anthropic.com>
AuthorDate: Mon Jun 1 15:25:54 2026 -0700
fix(embedded-sdk): validate embedded dashboard id format before use
Add defense-in-depth format validation for the embedded dashboard id
before it is interpolated into the iframe URL. The id is a
Superset-generated UUID (hexadecimal characters and hyphens), so a new
exported `validateEmbeddedDashboardId` helper rejects any value that does
not match that format.
This is a minor behavior change: a malformed id now throws instead of
being used as-is. A unit test file covers the helper, and a jest config
is added so the switchboard ES module is transformed during testing.
Co-Authored-By: Claude Opus 4.8 <no...@anthropic.com>
---
superset-embedded-sdk/jest.config.js | 24 +++++++++++++++++
superset-embedded-sdk/src/index.test.ts | 46 +++++++++++++++++++++++++++++++++
superset-embedded-sdk/src/index.ts | 17 +++++++++++-
3 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/superset-embedded-sdk/jest.config.js b/superset-embedded-sdk/jest.config.js
new file mode 100644
index 00000000000..a49b796ab5b
--- /dev/null
+++ b/superset-embedded-sdk/jest.config.js
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+module.exports = {
+ // @superset-ui/switchboard ships ES module syntax, so it must be
+ // transformed by babel rather than ignored as a node_modules dependency.
+ transformIgnorePatterns: ["/node_modules/(?!@superset-ui/switchboard)"],
+};
diff --git a/superset-embedded-sdk/src/index.test.ts b/superset-embedded-sdk/src/index.test.ts
new file mode 100644
index 00000000000..77aee04715c
--- /dev/null
+++ b/superset-embedded-sdk/src/index.test.ts
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { validateEmbeddedDashboardId } from "./index";
+
+describe("validateEmbeddedDashboardId", () => {
+ it("accepts a canonical uuid", () => {
+ expect(() =>
+ validateEmbeddedDashboardId("f4787a4f-2541-4f8a-9b5e-1e2d3c4b5a6f")
+ ).not.toThrow();
+ });
+
+ it("accepts a simple hexadecimal id", () => {
+ expect(() => validateEmbeddedDashboardId("abc123")).not.toThrow();
+ });
+
+ it.each([
+ ["../../evil"],
+ ["a/b"],
+ ["x?foo=bar"],
+ ["x#frag"],
+ ["a@b.com"],
+ ["foo bar"],
+ ["http://evil.com"],
+ [""],
+ ["%2e%2e"],
+ ])("rejects an id with an unexpected format: %p", (id) => {
+ expect(() => validateEmbeddedDashboardId(id)).toThrow();
+ });
+});
diff --git a/superset-embedded-sdk/src/index.ts b/superset-embedded-sdk/src/index.ts
index 2eb9f37181a..01fd9be930c 100644
--- a/superset-embedded-sdk/src/index.ts
+++ b/superset-embedded-sdk/src/index.ts
@@ -50,7 +50,9 @@ export type UiConfigType = {
};
export type EmbedDashboardParams = {
- /** The id provided by the embed configuration UI in Superset */
+ /** The id provided by the embed configuration UI in Superset.
+ * This is the UUID generated by Superset's embed configuration and is
+ * expected to contain only hexadecimal characters and hyphens. */
id: string;
/** The domain where Superset can be located, with protocol, such as: https://superset.example.com */
supersetDomain: string;
@@ -112,6 +114,17 @@ export type EmbeddedDashboard = {
setThemeMode: (mode: ThemeMode) => void;
};
+/**
+ * Validates that an embedded dashboard id has the expected format
+ * (the UUID produced by Superset's embed configuration). Throws on
+ * anything containing characters that are not part of that format.
+ */
+export function validateEmbeddedDashboardId(id: string): void {
+ if (typeof id !== 'string' || !/^[a-f0-9-]+$/i.test(id)) {
+ throw new Error('Invalid dashboard id format');
+ }
+}
+
/**
* Embeds a Superset dashboard into the page using an iframe.
*/
@@ -128,6 +141,8 @@ export async function embedDashboard({
referrerPolicy,
resolvePermalinkUrl,
}: EmbedDashboardParams): Promise<EmbeddedDashboard> {
+ validateEmbeddedDashboardId(id);
+
function log(...info: unknown[]) {
if (debug) {
console.debug(`[superset-embedded-sdk][dashboard ${id}]`, ...info);