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/05/30 17:28:26 UTC
(superset) 01/01: chore: guard recursive merge keys and invoke subprocess without a shell
This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch chore/js-merge-subprocess-hardening
in repository https://gitbox.apache.org/repos/asf/superset.git
commit 7f70ccd8bc66761545ba0d98510b548aa4228e1d
Author: Claude Code <no...@anthropic.com>
AuthorDate: Sat May 30 10:28:14 2026 -0700
chore: guard recursive merge keys and invoke subprocess without a shell
Two small code-quality hardening tweaks flagged by static analysis:
- `cal-heatmap` vendored helper: `mergeRecursive` now skips `__proto__`,
`constructor`, and `prototype` keys when copying properties, so a merged
source object can't reach the destination's prototype.
- `superset-mcp.js` launcher: the Superset import check now uses
`execFileSync(python, ['-c', 'import superset'])` instead of building a
shell command string, matching how the server process is already spawned
(`spawn(python, args)`).
No behavior change for normal inputs.
Co-Authored-By: Claude Opus 4.8 <no...@anthropic.com>
---
.../plugins/legacy-plugin-chart-calendar/src/vendor/cal-heatmap.ts | 4 ++++
superset/mcp_service/bin/superset-mcp.js | 4 ++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/superset-frontend/plugins/legacy-plugin-chart-calendar/src/vendor/cal-heatmap.ts b/superset-frontend/plugins/legacy-plugin-chart-calendar/src/vendor/cal-heatmap.ts
index 61f74e0d3ac..519f95b7103 100644
--- a/superset-frontend/plugins/legacy-plugin-chart-calendar/src/vendor/cal-heatmap.ts
+++ b/superset-frontend/plugins/legacy-plugin-chart-calendar/src/vendor/cal-heatmap.ts
@@ -4005,6 +4005,10 @@ function mergeRecursive(obj1, obj2) {
/*jshint forin:false */
for (var p in obj2) {
+ // Skip keys that could pollute the object prototype.
+ if (p === '__proto__' || p === 'constructor' || p === 'prototype') {
+ continue;
+ }
try {
// Property in destination object set; update its value.
if (obj2[p].constructor === Object) {
diff --git a/superset/mcp_service/bin/superset-mcp.js b/superset/mcp_service/bin/superset-mcp.js
index b9eb7c68780..4d190651998 100755
--- a/superset/mcp_service/bin/superset-mcp.js
+++ b/superset/mcp_service/bin/superset-mcp.js
@@ -59,7 +59,7 @@
* 4. Run npm publish with appropriate access rights
*/
-const { spawn, execSync } = require('child_process');
+const { spawn, execSync, execFileSync } = require('child_process');
const path = require('path');
const fs = require('fs');
@@ -176,7 +176,7 @@ function checkEnvironment() {
// Check if Superset is installed
try {
- execSync(`${python} -c "import superset"`, {
+ execFileSync(python, ['-c', 'import superset'], {
env: { ...process.env, PYTHONPATH: supersetRoot },
stdio: 'ignore'
});