Skip to content

Commit ca48c6f

Browse files
fix(security): redact malformed tool params
1 parent 275a9e8 commit ca48c6f

2 files changed

Lines changed: 31 additions & 0 deletions

File tree

apps/sim/lib/workflows/credentials/credential-extractor.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,4 +184,25 @@ describe('export sanitizer resource coverage', () => {
184184
{ type: 'custom-tool', params: { token: null, query: null } },
185185
])
186186
})
187+
188+
it.each([
189+
['string', 'plaintext-secret'],
190+
['array', ['plaintext-secret']],
191+
])('withholds malformed %s tool params', (_shape, params) => {
192+
vi.mocked(getBlock).mockReturnValue({
193+
name: 'Test',
194+
description: '',
195+
subBlocks: [{ id: 'field', title: 'Field', type: 'tool-input' }],
196+
outputs: {},
197+
} as never)
198+
199+
const sanitized = sanitizeWorkflowForSharing(
200+
stateWithSubBlock('tool-input', [{ type: 'custom-tool', params }]),
201+
{ redactOpaqueCredentialInputs: true }
202+
)
203+
204+
expect(sanitized.blocks?.b1?.subBlocks?.field?.value).toEqual([
205+
{ type: 'custom-tool', params: null },
206+
])
207+
})
187208
})

apps/sim/lib/workflows/credentials/credential-extractor.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { isPlainRecord } from '@sim/utils/object'
12
import { getToolInputParamConfigs } from '@/lib/workflows/search-replace/indexer'
23
import { WORKFLOW_SEARCH_SUBBLOCK_RESOURCE_TYPES } from '@/lib/workflows/search-replace/resources/registry'
34
import { setValueAtPath } from '@/lib/workflows/search-replace/value-walker'
@@ -290,6 +291,15 @@ function sanitizeToolInputValue(value: unknown, options: WorkflowSanitizationOpt
290291

291292
let sanitizedValue: unknown = value
292293
tools.forEach((tool, toolIndex) => {
294+
const storedTool = value[toolIndex]
295+
if (!isPlainRecord(storedTool)) {
296+
throw new Error(`Parsed tool input at index ${toolIndex} lost its object shape`)
297+
}
298+
if (storedTool.params != null && !isPlainRecord(storedTool.params)) {
299+
sanitizedValue = setValueAtPath(sanitizedValue, [toolIndex, 'params'], null)
300+
return
301+
}
302+
293303
const configs = getToolInputParamConfigs({ tool, toolIndex })
294304
const configByParamKey = new Map<
295305
string,

0 commit comments

Comments
 (0)