Fix elevated bash execution

This commit is contained in:
Levi Neely 2026-03-06 17:02:57 +01:00
parent 22453593e2
commit b913fcc644
7 changed files with 56 additions and 57 deletions

View File

@ -20,6 +20,7 @@ filesystem:
- "/dev/null"
- "/tmp"
- "{NAMESPACE}"
- "{XDG_RUNTIME_DIR}/superpowerd"
rwx:
- "{CWD}"
env:
@ -31,5 +32,8 @@ env:
- WAYLAND_DISPLAY
- USER
- AGENT_ID
- SUPERPOWERD_SESSION_TOKEN
- SUPERPOWERD_SOCKET_DIR
- XDG_RUNTIME_DIR
network:
unrestricted: true

View File

@ -111,5 +111,6 @@ env:
- PCLOUD_USER
- EDITOR
- GIT_SEQUENCE_EDITOR
- SUPERPOWERD_SESSION_TOKEN
network:
unrestricted: true

View File

@ -214,53 +214,15 @@ func executeCode(code, language string, timeout int, sandboxName string, trusted
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
defer cancel()
landrunPath, err := exec.LookPath("landrun")
if err != nil {
return "", fmt.Errorf("landrun not found: %v", err)
}
var cmd *exec.Cmd
switch language {
case "bash", "":
args := []string{}
// Add filesystem permissions from config
addPaths := func(flag string, paths []string) {
for _, p := range paths {
expanded := sandbox.ExpandPath(p, workDir)
if expanded == "" || strings.Contains(expanded, "{") {
continue // Skip unexpanded templates
}
if _, err := os.Stat(expanded); err == nil {
args = append(args, flag, expanded)
}
}
}
addPaths("--ro", cfg.Filesystem.RO)
addPaths("--rox", cfg.Filesystem.ROX)
addPaths("--rw", cfg.Filesystem.RW)
addPaths("--rwx", cfg.Filesystem.RWX)
// Network
if cfg.Network.Unrestricted {
args = append(args, "--unrestricted-network")
}
// Environment variables
for _, env := range cfg.Env {
if os.Getenv(env) != "" || env == "HOME" || env == "USER" || env == "PATH" {
args = append(args, "--env", env)
}
}
args = append(args, "--", "bash", "-c", code)
cmd = exec.CommandContext(ctx, landrunPath, args...)
wrapped := sandbox.WrapCommand(cfg, []string{"bash", "-c", code}, workDir)
cmd = exec.CommandContext(ctx, wrapped[0], wrapped[1:]...)
cmd.Dir = workDir
// Add new language cases here:
// case "python":
// args = append(args, "--", "python3", "-c", code)
// wrapped := sandbox.WrapCommand(cfg, []string{"python3", "-c", code}, workDir)
default:
return "", fmt.Errorf("unsupported language: %s (supported: bash)", language)
}

View File

@ -2,7 +2,10 @@ package sandbox
import (
"fmt"
"net"
"os"
"os/exec"
"path/filepath"
"sort"
"strings"
)
@ -107,6 +110,16 @@ func WrapCommand(cfg *Config, originalCmd []string, cwd string) []string {
args = append(args, "--")
args = append(args, originalCmd...)
// Wrap with superpowers run-session if superpowerd is running
if IsSuperpowerdRunning() {
if superpowersPath, err := exec.LookPath("superpowers"); err == nil {
// Insert --env SUPERPOWERD_SESSION_TOKEN after landrun
args = append([]string{args[0], "--env", "SUPERPOWERD_SESSION_TOKEN"}, args[1:]...)
// Wrap: superpowers run-session -- landrun ...
args = append([]string{superpowersPath, "run-session", "--"}, args...)
}
}
return args
}
@ -168,3 +181,21 @@ func pathExists(path string) bool {
_, err := os.Stat(path)
return err == nil
}
// IsSuperpowerdRunning checks if superpowerd daemon is running by testing socket connectivity
func IsSuperpowerdRunning() bool {
socketDir := os.Getenv("SUPERPOWERD_SOCKET_DIR")
if socketDir == "" {
socketDir = os.Getenv("XDG_RUNTIME_DIR")
if socketDir == "" {
return false
}
socketDir = filepath.Join(socketDir, "superpowerd")
}
conn, err := net.Dial("unixpacket", filepath.Join(socketDir, "superpowerd.sock"))
if err != nil {
return false
}
conn.Close()
return true
}

View File

@ -15,7 +15,9 @@
"aws",
"subagent",
"web_fetch",
"@anvilmcp/execute_code"
"@anvilmcp/execute_code",
"@superpowers-mcp-server/execute_elevated_bash",
"@superpowers-mcp-server/request_file"
],
"allowedTools": [
"code",
@ -30,7 +32,9 @@
"aws",
"subagent",
"web_fetch",
"@anvilmcp/execute_code"
"@anvilmcp/execute_code",
"@superpowers-mcp-server/execute_elevated_bash",
"@superpowers-mcp-server/request_file"
],
"toolsSettings": {
"shell": {

View File

@ -1,14 +1,7 @@
#!/bin/bash
SETTINGS_FILE="$HOME/.kiro/settings/cli.json"
MCP_CONFIG='{
"mcpServers": {
"anvilmcp": {
"command": "anvilmcp",
"args": []
}
}
}'
SETTINGS_FILE="$HOME/.kiro/settings/mcp.json"
MCP_CONFIG='{"mcpServers":{"anvilmcp":{"command":"anvilmcp","args":[]},"superpowers-mcp-server":{"command":"superpowers-mcp-server","args":[],"env":{"SUPERPOWERD_SESSION_TOKEN":"${SUPERPOWERD_SESSION_TOKEN}"},"autoApproveTools":["execute_elevated_bash","request_file"]}}}'
if ! command -v jq &> /dev/null; then
echo "Error: jq is required but not installed. Please install jq first." >&2
@ -17,12 +10,10 @@ fi
mkdir -p "$HOME/.kiro/settings"
if [ -f "$SETTINGS_FILE" ]; then
# Merge with existing settings
if [ -f "$SETTINGS_FILE" ] && [ -s "$SETTINGS_FILE" ]; then
jq -s '.[0] * .[1]' "$SETTINGS_FILE" <(echo "$MCP_CONFIG") > "$SETTINGS_FILE.tmp"
mv "$SETTINGS_FILE.tmp" "$SETTINGS_FILE"
else
# Create new settings file
echo "$MCP_CONFIG" | jq '.' > "$SETTINGS_FILE"
fi

View File

@ -2,9 +2,15 @@
"mcpServers": {
"anvilmcp": {
"command": "anvilmcp",
"autoApproveTools": ["execute_code"],
"args": []
},
"superpowers-mcp-server": {
"command": "superpowers-mcp-server",
"args": [],
"env": {}
"env": {
"SUPERPOWERD_SESSION_TOKEN": "${SUPERPOWERD_SESSION_TOKEN}"
},
"autoApproveTools": ["execute_elevated_bash", "request_file"]
}
}
}