Skip to content

Commit 3d0b07b

Browse files
waleedlatif1claude
andcommitted
fix(execute-command): throw on unresolved block refs, block env var override
- Throw a clear error when a block reference cannot be resolved instead of leaving raw <blockName.output> in the command (which the shell interprets as I/O redirection). Skip special prefixes (variable, loop, parallel) which are handled by their own collectors. - Filter user-supplied env vars to prevent overriding safe base env keys (PATH, HOME, SHELL, etc.) and block process-influencing variables (LD_PRELOAD, BASH_ENV, DYLD_INSERT_LIBRARIES, etc.). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 281f5bb commit 3d0b07b

File tree

1 file changed

+33
-2
lines changed
  • apps/sim/app/api/tools/execute-command/run

1 file changed

+33
-2
lines changed

apps/sim/app/api/tools/execute-command/run/route.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { type NextRequest, NextResponse } from 'next/server'
44
import { checkInternalAuth } from '@/lib/auth/hybrid'
55
import { isExecuteCommandEnabled } from '@/lib/core/config/feature-flags'
66
import { generateRequestId } from '@/lib/core/utils/request'
7-
import { normalizeName, REFERENCE } from '@/executor/constants'
7+
import { normalizeName, REFERENCE, SPECIAL_REFERENCE_PREFIXES } from '@/executor/constants'
88
import { type OutputSchema, resolveBlockReference } from '@/executor/utils/block-reference'
99
import {
1010
createEnvVarPattern,
@@ -35,6 +35,31 @@ function getSafeBaseEnv(): NodeJS.ProcessEnv {
3535
return env
3636
}
3737

38+
const BLOCKED_ENV_KEYS = new Set([
39+
...SAFE_ENV_KEYS,
40+
'NODE_ENV',
41+
'LD_PRELOAD',
42+
'LD_LIBRARY_PATH',
43+
'DYLD_INSERT_LIBRARIES',
44+
'BASH_ENV',
45+
'ENV',
46+
])
47+
48+
/**
49+
* Filters user-supplied env vars to prevent overriding safe base env
50+
* and injecting process-influencing variables.
51+
*/
52+
function filterUserEnv(env?: Record<string, string>): Record<string, string> {
53+
if (!env) return {}
54+
const filtered: Record<string, string> = {}
55+
for (const [key, value] of Object.entries(env)) {
56+
if (!BLOCKED_ENV_KEYS.has(key)) {
57+
filtered[key] = value
58+
}
59+
}
60+
return filtered
61+
}
62+
3863
interface Replacement {
3964
index: number
4065
length: number
@@ -135,6 +160,12 @@ function collectTagReplacements(
135160
})
136161

137162
if (!result) {
163+
const isSpecialPrefix = SPECIAL_REFERENCE_PREFIXES.some((prefix) => blockName === prefix)
164+
if (!isSpecialPrefix) {
165+
throw new Error(
166+
`Block reference "<${tagName}>" could not be resolved. Check that the block name and field path are correct.`
167+
)
168+
}
138169
continue
139170
}
140171

@@ -207,7 +238,7 @@ function executeCommand(
207238
timeout: options.timeout,
208239
cwd: options.cwd || undefined,
209240
maxBuffer: MAX_BUFFER,
210-
env: { ...getSafeBaseEnv(), ...options.env },
241+
env: { ...getSafeBaseEnv(), ...filterUserEnv(options.env) },
211242
},
212243
(error, stdout, stderr) => {
213244
if (error) {

0 commit comments

Comments
 (0)