1P by neo 2달전 | favorite | 댓글 1개

QuickJS - WebAssembly QuickJS 샌드박스에서 JavaScript 실행

이 TypeScript 패키지는 QuickJS 엔진을 사용하여 WebAssembly 샌드박스 내에서 JavaScript 코드를 안전하게 실행할 수 있게 해줌. 신뢰할 수 없는 코드를 안전하게 격리하고 실행하기에 적합하며, WebAssembly로 컴파일된 경량의 빠른 QuickJS 엔진을 활용하여 견고한 코드 실행 환경을 제공함.

특징

  • 보안: 신뢰할 수 없는 JavaScript 코드를 안전하고 격리된 환경에서 실행할 수 있음
  • 파일 시스템: 가상 파일 시스템을 마운트할 수 있음
  • 커스텀 Node 모듈: 커스텀 Node 모듈을 마운트할 수 있음
  • Fetch 클라이언트: http(s) 호출을 할 수 있는 fetch 클라이언트를 제공할 수 있음
  • 테스트 러너: 테스트 러너와 chai 기반의 expect를 포함함
  • 성능: 경량의 효율적인 QuickJS 엔진의 이점을 누릴 수 있음
  • 다양성: 기존 TypeScript 프로젝트와 쉽게 통합할 수 있음
  • 단순성: 샌드박스 내에서 JavaScript 코드를 실행하고 관리하기 위한 사용자 친화적인 API를 제공함

전체 문서 보기

저장소에서 예제 찾기

기본 사용법

다음은 패키지를 사용하는 간단한 예제임:

import { quickJS } from '@sebastianwessel/quickjs'

// QuickJS wasm 로드 및 초기화와 같은 일반 설정
// 리소스 집약적인 작업이므로 가능하면 한 번만 수행해야 함
const { createRuntime } = await quickJS()

// js 코드를 실행할 때마다 런타임 인스턴스를 생성함
const { evalCode } = await createRuntime({
  allowFetch: true, // fetch를 주입하고 코드가 데이터를 가져올 수 있도록 허용함
  allowFs: true, // 가상 파일 시스템을 마운트하고 node:fs 모듈을 제공함
  env: {
    MY_ENV_VAR: 'env var value'
  },
})

const result = await evalCode(`
  import { join } as path from 'path'
  const fn = async ()=>{
    console.log(join('src','dist')) // 호스트 시스템에서 "src/dist"를 로그로 출력함
    console.log(env.MY_ENV_VAR) // 호스트 시스템에서 "env var value"를 로그로 출력함
    const url = new URL('https://example.com')
    const f = await fetch(url)
    return f.text()
  }
  export default await fn()
`)

console.log(result) // { ok: true, data: '<!doctype html>\n<html>\n[....]</html>\n' }

크레딧

이 라이브러리는 다음을 기반으로 함:

  • quickjs-emscripten
  • quickjs-emscripten-sync
  • memfs
  • Chai

사용된 도구:

  • Bun
  • Biome
  • Hono
  • poolifier-web-worker
  • tshy
  • autocannon

라이선스

이 프로젝트는 MIT 라이선스 하에 있음.


이 패키지는 TypeScript 애플리케이션 내에서 JavaScript 코드를 안전하게 실행하려는 개발자에게 이상적이며, QuickJS WebAssembly 샌드박스를 통해 성능과 안전성을 보장함.

GN⁺의 정리

이 기사는 QuickJS 엔진을 사용하여 WebAssembly 샌드박스 내에서 JavaScript 코드를 안전하게 실행하는 방법을 설명함. 이는 신뢰할 수 없는 코드를 격리하고 실행하는 데 매우 유용함. QuickJS는 경량이면서도 빠른 성능을 제공하며, TypeScript 프로젝트와 쉽게 통합할 수 있는 장점을 가짐. 이와 유사한 기능을 제공하는 프로젝트로는 Deno와 Node.js가 있음.

Hacker News 의견
  • quickjs-emscripten 라이브러리의 저자가 라이브러리의 표준 라이브러리를 칭찬함

    • 브라우저나 번들러에서 실행해봤는지 질문함
    • Webpack과 같은 번들러와의 호환성 문제를 지적함
    • 보안 경고: 라이브러리가 게스트 코드가 호스트의 fetch 함수와 동일한 쿠키를 사용하여 fetch를 호출할 수 있게 함
    • 신뢰할 수 없는 코드를 실행할 때 주의해야 함
    • quickjs-emscripten이 저수준이고 마법 같은 기능을 피하는 이유는 보안성을 보장하기 위함
    • 신뢰할 수 없는 코드를 실행할 때 샌드박스와 API를 신중하게 감사해야 함
    • Figma의 플러그인 샌드박스 보안에 대한 블로그 포스트를 참고할 것을 권장함
  • 이전 직장에서 quickjs-emscripten 사용 중 많은 "segmentation faults"와 오류를 경험했음

    • 프로젝트가 중단되었고, 다시 한다면 공식적으로 지원되는 wasm 번들을 사용할 것임
  • JavaScript를 샌드박스하는 여러 방법이 있음

    • DOM 접근을 샌드박스하는 방법이 있는지 질문함
    • iframes가 유일한 기술이지만 무겁고 느림
    • 플러그인을 호스팅하는 앱을 작성 중이며, 플러그인에 DOM 접근을 허용하면 문제가 생길 수 있음
  • 브라우저에서 실행 가능한지 질문함

    • 지원되는 환경에 대한 언급을 찾을 수 없음
  • quickjs를 사용해봤으나 최종적으로 isolated-vm을 선택했음

    • 두 라이브러리 모두 보안 요구사항을 충족했으나, isolated-vm이 성능 면에서 더 우수했음
  • 다른 JS 샌드박스 라이브러리의 저자가 quickjs-emscripten 접근법을 흥미롭게 생각함

    • JS-in-JS 또는 JS-in-WASM이 높은 수준의 격리를 제공한다고 언급함
    • Node.js가 격리와 샌드박싱을 염두에 두고 설계되지 않았음을 지적함
    • createRuntimefetch 외에 호스트 환경에 대한 호출을 정의할 수 있는지 질문함
    • 브라우저 지원이 유용할 것이라고 언급함
  • 이 라이브러리를 통해 사용자가 제공한 JS 코드를 실행할 수 있을 것이라고 생각함

    • 번들러를 샌드박스 환경에서 실행하는 방법에 대한 추천을 요청함
  • QuickJS의 성능이 호스트 JS VM과 경쟁할 수 없음을 언급함

    • 오래된 C 인터프리터나 JavaScript로 구현된 인터프리터보다는 빠름
  • quickjs-emscripten의 고수준 래퍼를 작업 중이었음

    • quickjs-emscripten의 API가 quickjs의 C API와 매우 유사하여 사용하기 어려움
    • require() 지원 구현이 어려움
    • 모듈 파일을 메모리 파일 시스템에 미리 로드하는 방법을 사용함
  • quickjs-emscripten-sync 라이브러리가 호스트와 게스트 함수의 자동 동기화를 제공하는데, 이는 큰 공격 표면이 될 수 있음

    • 샌드박스를 탈출할 가능성에 대해 우려함
  • wasm으로 컴파일되었기 때문에 브라우저에서 실행 가능한지 질문함

    • 쿠키를 첨부하지 않고 fetch 요청을 할 수 있는지 궁금해함