mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-26 03:31:24 +08:00
Add JavaScript execution safety limits and improve error handling
- Add 1MB code size limit to prevent memory issues - Improve timeout error handling with proper cleanup logging - Remove host environment exposure and fix file descriptor leaks in worker
This commit is contained in:
parent
9f1c8f2c17
commit
71d35eddf7
@ -107,7 +107,7 @@ class JsServer {
|
||||
timeout: timeout ?? DEFAULT_TIMEOUT
|
||||
})
|
||||
|
||||
const { combinedOutput, isError } = formatExecutionResult(result as any)
|
||||
const { combinedOutput, isError } = formatExecutionResult(result)
|
||||
|
||||
return {
|
||||
content: [
|
||||
|
||||
@ -41,6 +41,12 @@ export class JsService {
|
||||
throw new Error('JavaScript code must be a non-empty string')
|
||||
}
|
||||
|
||||
// Limit code size to 1MB to prevent memory issues
|
||||
const MAX_CODE_SIZE = 1_000_000
|
||||
if (code.length > MAX_CODE_SIZE) {
|
||||
throw new Error(`JavaScript code exceeds maximum size of ${MAX_CODE_SIZE / 1_000_000}MB`)
|
||||
}
|
||||
|
||||
return new Promise<JsExecutionResult>((resolve, reject) => {
|
||||
const worker = createJsWorker({
|
||||
workerData: { code },
|
||||
@ -98,7 +104,9 @@ export class JsService {
|
||||
|
||||
timeoutId = setTimeout(() => {
|
||||
logger.warn(`JavaScript execution timed out after ${timeout}ms`)
|
||||
void settleError(new Error('JavaScript execution timed out'))
|
||||
settleError(new Error('JavaScript execution timed out')).catch((err) => {
|
||||
logger.error('Error during timeout cleanup:', err instanceof Error ? err : new Error(String(err)))
|
||||
})
|
||||
}, timeout)
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { mkdtemp, open, readFile, rm } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { env } from 'node:process'
|
||||
import { WASI } from 'node:wasi'
|
||||
import { parentPort, workerData } from 'node:worker_threads'
|
||||
|
||||
@ -40,7 +39,7 @@ async function runQuickJsInSandbox(jsCode: string): Promise<JsExecutionResult> {
|
||||
const wasi = new WASI({
|
||||
version: 'preview1',
|
||||
args: ['qjs', '-e', jsCode],
|
||||
env,
|
||||
env: {}, // Empty environment for security - don't expose host env vars
|
||||
stdin: 0,
|
||||
stdout: stdoutHandle.fd,
|
||||
stderr: stderrHandle.fd,
|
||||
@ -60,10 +59,14 @@ async function runQuickJsInSandbox(jsCode: string): Promise<JsExecutionResult> {
|
||||
}
|
||||
}
|
||||
|
||||
await stdoutHandle.close()
|
||||
// Close handles before reading files to prevent descriptor leak
|
||||
const _stdoutHandle = stdoutHandle
|
||||
stdoutHandle = undefined
|
||||
await stderrHandle.close()
|
||||
await _stdoutHandle.close()
|
||||
|
||||
const _stderrHandle = stderrHandle
|
||||
stderrHandle = undefined
|
||||
await _stderrHandle.close()
|
||||
|
||||
const capturedStdout = await readFile(stdoutPath, 'utf8')
|
||||
const capturedStderr = await readFile(stderrPath, 'utf8')
|
||||
|
||||
Loading…
Reference in New Issue
Block a user