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 <[email protected]>
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 <[email protected]>
---
 .../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'
         });

Reply via email to