codeant-ai-for-open-source[bot] commented on code in PR #41007:
URL: https://github.com/apache/superset/pull/41007#discussion_r3493355626
##########
superset-frontend/src/theme/ThemeController.ts:
##########
@@ -696,9 +702,18 @@ export class ThemeController {
hasValidDefault && !this.isEmptyTheme(defaultTheme);
const hasCustomDark = hasValidDark && !this.isEmptyTheme(darkTheme);
+ const modeMap: Record<string, ThemeMode> = {
+ default: ThemeMode.DEFAULT,
+ dark: ThemeMode.DARK,
+ system: ThemeMode.SYSTEM,
+ };
+ const bootstrapDefaultMode: ThemeMode =
+ (defaultMode && modeMap[defaultMode]) || ThemeMode.SYSTEM;
Review Comment:
**Suggestion:** The mode parsing uses direct object indexing with an
untrusted string key, so special keys like `constructor`/`toString` can resolve
to inherited function values and set `bootstrapDefaultMode` to a non-ThemeMode
value. This can leave the controller in an invalid mode state and persist
invalid data to storage; guard with an own-key check (or `Object.hasOwn`/`Map`)
and only accept explicit enum values. [type error]
<details>
<summary><b>Severity Level:</b> Major ⚠️</summary>
```mdx
- ❌ ThemeController currentMode becomes non-enum, breaking mode checks.
- ⚠️ Theme mode saved to localStorage as function string.
```
</details>
<details>
<summary><b>Steps of Reproduction ✅ </b></summary>
```mdx
1. Configure the backend to use a prototype-key value for the default mode,
for example by
overriding `THEME_DEFAULT_MODE` to `'toString'` (instead of
`"default"|"dark"|"system"`)
in the deployment config at `superset/config.py:1117` or via
`superset_config.py`
overrides.
2. Start Superset and load any page that uses the standard bootstrap
payload; the server
builds this payload in `common_bootstrap_payload()` at
`superset/views/base.py:569-566`,
which calls `get_theme_bootstrap_data()` at `superset/views/base.py:381-50`
and injects
`"defaultMode": app.config["THEME_DEFAULT_MODE"]` into the JSON at
`superset/views/base.py:47`.
3. On the frontend, the initial theme controller is constructed and calls
`loadBootstrapData()` at
`superset-frontend/src/theme/ThemeController.ts:690-717`, which
destructures `theme.defaultMode` from `getBootstrapData()` and then computes
`bootstrapDefaultMode` via `const modeMap = { default, dark, system }` and
`const
bootstrapDefaultMode: ThemeMode = (defaultMode && modeMap[defaultMode]) ||
ThemeMode.SYSTEM;` at
`superset-frontend/src/theme/ThemeController.ts:705-711`; for
`defaultMode === 'toString'`, `modeMap[defaultMode]` resolves to the
inherited
`Object.prototype.toString` function, not a `ThemeMode` enum value.
4. The constructor assigns `this.bootstrapDefaultMode =
bootstrapDefaultMode` at
`superset-frontend/src/theme/ThemeController.ts:136-141`, and
`determineInitialMode()` at
`superset-frontend/src/theme/ThemeController.ts:790-809` returns this
non-enum value when
there is no saved mode or explicit `initialMode`; `this.currentMode` is now
a function,
which is persisted by `persistMode()` at
`superset-frontend/src/theme/ThemeController.ts:944-949` (stored as a string
like
`'function toString() { ... }'` in localStorage) and returned by
`getCurrentMode()` at
`superset-frontend/src/theme/ThemeController.ts:323-325`, causing subsequent
mode checks
and saved-mode restoration logic (`loadSavedMode()` at lines 815-821 and
`isValidThemeMode()` at 834-850) to operate on an invalid mode state.
```
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=256ab108b2ad4945b2215325356b79ce&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
[](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=256ab108b2ad4945b2215325356b79ce&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent 🤖 </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/src/theme/ThemeController.ts
**Line:** 710:711
**Comment:**
*Type Error: The mode parsing uses direct object indexing with an
untrusted string key, so special keys like `constructor`/`toString` can resolve
to inherited function values and set `bootstrapDefaultMode` to a non-ThemeMode
value. This can leave the controller in an invalid mode state and persist
invalid data to storage; guard with an own-key check (or `Object.hasOwn`/`Map`)
and only accept explicit enum values.
Validate the correctness of the flagged issue. If correct, How can I resolve
this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask
user if the user wants to fix the rest of the comments as well. if said yes,
then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41007&comment_hash=1cfbeaace8bc9d1da152297830b2f1dfcf490d3985dfbf0ee70546f94f6f87ba&reaction=like'>👍</a>
| <a
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41007&comment_hash=1cfbeaace8bc9d1da152297830b2f1dfcf490d3985dfbf0ee70546f94f6f87ba&reaction=dislike'>👎</a>
##########
superset/views/base.py:
##########
@@ -423,6 +423,7 @@ def get_theme_bootstrap_data() -> dict[str, Any]:
"theme": {
"default": default_theme,
"dark": dark_theme,
+ "defaultMode": app.config["THEME_DEFAULT_MODE"],
Review Comment:
**Suggestion:** The backend forwards `THEME_DEFAULT_MODE` without validating
allowed values, so a typo/misconfigured value is silently accepted and the
frontend falls back to a different mode than intended. Validate this config
server-side against `default|dark|system` (and normalize casing) before sending
bootstrap data to avoid incorrect default-theme behavior. [logic error]
<details>
<summary><b>Severity Level:</b> Major ⚠️</summary>
```mdx
- ⚠️ Misconfigured THEME_DEFAULT_MODE silently falls back to system.
- ⚠️ Deployment cannot enforce desired default theme mode.
```
</details>
<details>
<summary><b>Steps of Reproduction ✅ </b></summary>
```mdx
1. Misconfigure the deployment’s theme default mode by setting
`THEME_DEFAULT_MODE` to an
unsupported value such as `"light"` (instead of `"default"`, `"dark"`, or
`"system"`) in
the configuration around `superset/config.py:1115-1117` or via
`superset_config.py`
overrides; note that the comment documents valid values but no runtime
validation is
enforced.
2. Start Superset and request any regular UI page; the server builds the
bootstrap payload
in `common_bootstrap_payload()` at `superset/views/base.py:569-566`, which
calls
`get_theme_bootstrap_data()` at `superset/views/base.py:381-50` and returns
a `theme`
object including `"defaultMode": app.config["THEME_DEFAULT_MODE"]` at
`superset/views/base.py:43-47`, so the invalid string `"light"` is forwarded
unchanged to
the frontend.
3. On the frontend, `ThemeController` is constructed in
`superset-frontend/src/theme/ThemeController.ts:114-182` and calls
`loadBootstrapData()`
at `superset-frontend/src/theme/ThemeController.ts:690-717`, which reads
`theme.defaultMode` from bootstrap data and computes `const
bootstrapDefaultMode:
ThemeMode = (defaultMode && modeMap[defaultMode]) || ThemeMode.SYSTEM;` at
`superset-frontend/src/theme/ThemeController.ts:705-711`; because `"light"`
is not a key
in `modeMap`, `modeMap[defaultMode]` is `undefined` and the controller
silently falls back
to `ThemeMode.SYSTEM`.
4. With no saved mode and no explicit `initialMode`,
`determineInitialMode()` at
`superset-frontend/src/theme/ThemeController.ts:790-809` returns
`this.bootstrapDefaultMode` (which is `ThemeMode.SYSTEM` despite the
deployment intending
`"light"/default"`), so sessions start in system-following mode instead of
the configured
behavior; there is no server-side warning or validation in
`get_theme_bootstrap_data()` at
`superset/views/base.py:381-50`, so administrators receive no signal that
their
configuration typo is being ignored.
```
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=2d2941bf9d4943d38893bd417796ebde&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
[](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=2d2941bf9d4943d38893bd417796ebde&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent 🤖 </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset/views/base.py
**Line:** 426:426
**Comment:**
*Logic Error: The backend forwards `THEME_DEFAULT_MODE` without
validating allowed values, so a typo/misconfigured value is silently accepted
and the frontend falls back to a different mode than intended. Validate this
config server-side against `default|dark|system` (and normalize casing) before
sending bootstrap data to avoid incorrect default-theme behavior.
Validate the correctness of the flagged issue. If correct, How can I resolve
this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask
user if the user wants to fix the rest of the comments as well. if said yes,
then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41007&comment_hash=cff334f88cfcedacf2e9e9f98e8311a5afdaa4540cce4740916e7216ba753b03&reaction=like'>👍</a>
| <a
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41007&comment_hash=cff334f88cfcedacf2e9e9f98e8311a5afdaa4540cce4740916e7216ba753b03&reaction=dislike'>👎</a>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]