Visual Studio Code를 프로세스 샌드박싱으로 마이그레이션
보안과 VS Code 아키텍처 모두에 득이 되는 일
2022년 11월 28일, Benjamin Pasero 작성, @BenjaminPasero
Electron 렌더러 프로세스에서 샌드박스를 활성화하는 것은 Visual Studio Code와 같은 안전하고 안정적인 Electron 애플리케이션에 필수적인 요구 사항입니다. 샌드박스는 대부분의 시스템 리소스에 대한 액세스를 제한하여 악성 코드가 초래할 수 있는 피해를 줄입니다. 이 블로그 게시물에서는 2020년 초에 시작하여 2023년 초에 완료할 예정인 VS Code 프로세스 샌드박싱 활성화 여정을 자세히 살펴보겠습니다. 프로세스 샌드박싱의 어려움을 이해하는 데 도움이 되도록 이 블로그 게시물에서는 VS Code 프로세스 모델의 세부 정보와 이 여정 동안 어떻게 발전했는지도 설명합니다.
이것은 거의 모든 VS Code 구성 요소에 대한 기본적인 아키텍처 변경과 코드 수정이 필요했기 때문에 팀의 노력으로 이루어졌습니다. VS Code 프로세스 아키텍처는 개편되었고 그 과정에서 크게 강화되었습니다. 우리는 다른 사람들이 배울 수 있는 귀중한 통찰력을 제공하기를 바라는 주요 이정표를 강조합니다. 지난 몇 달 동안 프로세스 샌드박스 모드는 VS Code Insiders에서 성공적으로 실행되어 이 변경 사항의 영향을 파악할 수 있었습니다. 문제를 발견하거나 경험을 개선할 방법에 대한 제안이 있거나 일반적인 질문이 있으면 언제든지 저희에게 연락해 주세요.
VS Code, Electron 또는 샌드박싱에 익숙하지 않다면 먼저 블로그 게시물 끝에 있는 용어 섹션을 검토하는 것이 좋습니다. 거기에서 사용된 용어에 대한 설명과 배경 자료에 대한 링크를 찾을 수 있습니다.
프로세스 샌드박싱이란?
오랫동안 Electron은 HTML 및 JavaScript에서 Node.js API를 직접 사용할 수 있도록 허용했습니다. 아래 코드 조각은 사용자에게 "Hello World"를 출력할 뿐만 아니라 로컬 디스크의 파일에도 쓰는 간단한 웹 페이지의 예입니다.

사용자에게 웹 페이지를 표시하는 데 책임이 있는 Electron 프로세스를 렌더러 프로세스라고 합니다. 렌더러 프로세스의 샌드박스 모드를 활성화하면 보안이 향상되고 웹 모델과 더 잘 일치하도록 기능이 제한됩니다. HTML과 JavaScript는 여전히 허용되지만 Node.js 사용은 허용되지 않습니다. 시스템 리소스에 액세스해야 하는 렌더러 프로세스의 구성 요소는 샌드박스 처리되지 않은 다른 프로세스로 위임해야 합니다.
아래 코드는 더 이상 Node.js에 의존하지 않지만 설정을 업데이트하는 기능을 제공하는 vscode 전역 변수를 사용합니다. 이 메서드의 구현은 Node.js에 액세스할 수 있는 다른 프로세스로 메시지를 보내는 것을 포함합니다. 따라서 더 이상 동기적으로 실행되지 않고 비동기적으로 실행됩니다.

렌더러 프로세스에서 vscode 전역 변수를 얻게 된 방법과 구현 방법은 아래 타임라인 섹션에 자세히 설명되어 있습니다.
렌더러 프로세스에서 Node.js를 차단하는 것은 권장되는 Electron 보안 권장 사항입니다. 과거에 공격자가 렌더러 프로세스에서 임의의 Node.js 코드를 실행할 수 있었던 보안 문제가 있었습니다. 샌드박스 처리된 렌더러 프로세스는 이러한 공격의 위험을 크게 줄여줍니다.
어떻게 여기까지 왔는가?
렌더러 프로세스에서 모든 Node.js 종속성을 제거하는 것과 같은 대규모 변경은 회귀 및 버그의 위험을 수반합니다. 이전에 단일 프로세스에서 실행되었던 코드는 분할되어 여러 프로세스에서 실행되어야 합니다. 네이티브이며 웹 패키징할 수 없는 Node 모듈도 이동해야 합니다. Node.js Buffer와 같은 특정 전역 개체는 Uint8Array와 같은 브라우저 호환 변형으로 대체해야 합니다.
아래 다이어그램은 샌드박스 노력이 시작되기 전의 프로세스 아키텍처를 보여줍니다. 보시다시피 대부분의 프로세스는 렌더러 프로세스에서 포크된 Node.js 자식 프로세스(녹색)입니다. (프로세스 간 통신) IPC의 대부분은 Node.js 소켓을 통해 구현되며 렌더러 프로세스는 Node.js API의 주요 클라이언트입니다. 예를 들어 파일을 읽고 쓰기 위해 그렇습니다.

우리는 별도의 VS Code 애플리케이션을 샌드박스 처리하지 않고 프로세스 샌드박싱 작업을 하기로 결정했습니다. VS Code 렌더러 프로세스를 점진적으로 샌드박스 준비 상태로 만들고 마지막에 스위치를 켜고 싶었습니다. 지난 몇 년 동안 우리는 샌드박스 목표에 기여하는 변경 사항을 포함하는 월간 VS Code 안정 버전 릴리스를 배포했지만 아직 완전히 활성화하지는 않았습니다. 비행 중에 근본적으로 재구축되는 비행기를 조종한다고 상상해 보세요. 그리고 우리 경우에 사용자는 VS Code의 변경 사항을 거의 인지하지 못했습니다.
기술 타임라인
다음 섹션에서는 지난 몇 년 동안 샌드박싱이 어떻게 이루어졌는지 자세히 설명합니다. 주요 작업은 렌더러 프로세스에서 모든 Node.js 종속성을 제거하는 것이었지만, 그 과정에서 MessagePort의 도움으로 효율적인 샌드박스 준비 IPC 솔루션을 찾는 것과 같은 더 많은 과제가 발생했으며, 렌더러 프로세스에서 포크할 수 있는 다양한 Node.js 자식 프로세스를 위한 새로운 호스트를 찾는 것과 같은 과제가 발생했습니다.
대부분의 경우 주제의 순서는 실제 타임라인을 따릅니다. 각 섹션을 간결하게 유지하기 위해 특정 기술 측면을 더 자세히 설명하는 다른 문서 및 튜토리얼로 연결합니다. 이 작업은 2020년 초에 계획되었지만 이 작업을 도운 이전 작업의 일부를 제외하는 것은 불공평합니다. 자세히 살펴보겠습니다…
거인의 어깨 위에 서서
2020년 초 샌드박싱을 고려하기 시작했을 때 우리는 이미 웹 브라우저에서 실행할 수 있는 VS Code 버전을 출시했습니다. 브라우저에서 vscode.dev를 실행하고 웹용 Visual Studio Code를 볼 수 있습니다. 웹용 VS Code를 만드는 동안 Node.js 종속성을 작업대에서 제거하는 방법을 배웠습니다. 이는 주요 VS Code 사용자 인터페이스 창입니다.

Node.js에 대한 종속성을 제거한다는 것은 대안을 찾는 것을 의미했습니다. 예를 들어 Node.js Buffer 유형에 대한 종속성은 브라우저 환경에서 Uint8Array로 대체되는 VSBuffer 등가물로 대체되었습니다. 일부 Node.js 모듈(oniguruma, iconv-lite)을 웹 환경에서 실행하도록 패키징할 수도 있었습니다.

하지만 웹용 VS Code가 현실화되기 전에도 원격 호스트(예: SSH 연결을 통해)에서 소스 코드를 편집할 수 있도록 하는 원격 개발 지원을 활성화했습니다(이후 GitHub Codespaces까지 지원). 원격 개발의 경우 UI 관련 VS Code 부분을 로컬에서 실행하고 실제 파일 작업은 원격 머신에서 실행하는 솔루션을 구현해야 했습니다. 이 모델은 샌드박스 처리된 작업대에도 적용되며, 권한 있는 작업은 다른 프로세스에서 실행되어야 합니다. 두 경우 모두 렌더러 프로세스는 IPC를 통해 권한 있는 호스트와 통신하여 작업을 수행합니다.
렌더러에서 통신 채널 활성화
렌더러 프로세스에서 Node.js를 사용할 수 없는 경우 Node.js를 사용할 수 있는 다른 프로세스로 작업을 위임해야 합니다. 웹 컨텍스트에서 한 가지 해결책은 HTTP 메서드를 사용하는 것이며, 서버가 요청을 수락합니다. 그러나 이것은 데스크톱 애플리케이션에 대한 최상의 솔루션처럼 느껴지지 않았습니다. 로컬 서버를 포트에서 실행하면 보안상의 이유로 방화벽에 의해 차단될 수 있기 때문입니다.
Electron은 렌더러 프로세스에 사전 로딩 스크립트를 주입할 수 있는 기능을 제공하며, 이는 기본 스크립트가 실행되기 전에 실행됩니다. 이러한 스크립트는 Electron 자체의 IPC 메커니즘에 액세스할 수 있습니다. 사전 로딩 스크립트는 컨텍스트 브리지 API를 통해 렌더러의 기본 스크립트에 사용 가능한 API를 강화할 수 있습니다. 사전 로딩 스크립트는 Electron의 IPC를 직접 사용할 수 있지만 기본 스크립트는 그렇지 않습니다. 따라서 사전 로딩 스크립트에서 컨텍스트 브리지를 통해 기본 스크립트로 특정 메서드를 노출합니다. 처음에 사용했던 예에서 설정을 업데이트하는 메서드를 사전 로딩 스크립트에서 기본 스크립트로 노출하는 방법은 다음과 같습니다.

사전 로딩 스크립트는 권한 있는 코드와 권한 없는 코드를 분리하는 기본 구성 요소입니다. 예를 들어 디스크에 파일을 쓰는 것은 기본 스크립트에서 사전 로딩 스크립트로, 거기에서 Node.js에 액세스할 수 있는 기본 프로세스로 이동하는 IPC 메시지를 의미합니다.

메시지 포트를 통한 빠른 프로세스 간 통신
사전 로딩 스크립트를 도입함으로써 렌더러 프로세스는 Electron 기본 프로세스와 통신하여 작업을 예약할 수 있습니다. 그러나 Electron 애플리케이션에서는 기본 프로세스가 사용자 입력(예: 키보드 및 마우스)을 처리하는 책임도 있기 때문에 너무 많은 작업으로 기본 프로세스를 과부하하지 않는 것이 중요합니다. 바쁜 기본 프로세스는 응답성이 떨어지는 사용자 인터페이스를 초래할 수 있습니다.
이것은 우리가 전에 보았던 문제였습니다. 샌드박싱 작업을 하기 전에도 성능 집약적인 코드를 백그라운드 프로세스인 VS Code 공유 프로세스로 오프로드하는 데 관심이 있었습니다. 이 프로세스는 모든 작업대 창과 기본 프로세스가 통신할 수 있는 숨겨진 창입니다. 예를 들어 확장 프로그램을 설치할 때 공유 프로세스로 요청이 전송되어 전체 작업을 수행합니다.
그러나 공유 프로세스와의 통신은 Node.js 소켓을 통해 구현되었습니다. 이것은 기본 프로세스가 전혀 통신에 관여하지 않기 때문에 기본 프로세스에 대한 오버헤드가 제로라는 장점이 있었습니다. 단점은 샌드박스 처리된 렌더러에서는 Node.js 소켓 통신이 불가능하다는 것입니다. Node.js API를 사용할 수 없기 때문입니다.
메시지 포트는 두 프로세스 간에 IPC 채널을 설정하여 두 프로세스를 연결하는 강력한 방법을 제공합니다. 완전히 샌드박스 처리된 렌더러 프로세스조차도 브라우저에서 웹 API로 제공되기 때문에 메시지 포트를 사용할 수 있습니다. Node.js 소켓 통신을 메시지 포트로 대체함으로써 기본 프로세스를 관여시키지 않고 성능 측면을 유지하면서 샌드박스 호환 IPC 솔루션을 갖출 수 있었습니다.
프로세스 경계를 넘어 메시지 포트를 전달하는 것은 복잡하며, 특히 사전 로딩 스크립트가 있는 샌드박스 처리된 렌더러 프로세스로는 더욱 그렇습니다. 시퀀스는 아래 다이어그램에 요약되어 있습니다.
- 공유 프로세스는 메시지 포트 P1과 P2를 생성하고 P1을 보유합니다.
- P2는 Electron IPC를 통해 기본 프로세스로 전송됩니다.
- 기본 프로세스는 P2를 요청하는 렌더러 프로세스로 전달합니다.
- P2는 해당 렌더러 프로세스의 사전 로딩 스크립트에 도착합니다.
- 사전 로딩 스크립트는 P2를 렌더러 기본 스크립트로 전달합니다.
- 기본 스크립트는 P2를 수신하고 이를 사용하여 직접 메시지를 보낼 수 있습니다.

렌더러의 출처 변경
웹 브라우저에서는 URL을 입력하면 콘텐츠가 로드되어 표시됩니다. Electron에서는 URL을 입력하는 대신 애플리케이션이 로드하고 표시할 콘텐츠를 결정합니다. 따라서 VS Code를 열면 작업대 콘텐츠를 표시하기 위해 미리 구성된 URL을 가진 창이 로드됩니다.
VS Code의 경우 이 URL은 로컬 디스크의 실제 파일에 대한 포인터(file://<path to file on disk>)를 사용했습니다. 샌드박싱 작업의 일부로 이 접근 방식을 재검토했습니다. 로컬 파일 프로토콜은 HTTPS 프로토콜보다 덜 엄격한 특정 보안 가정을 만들기 때문입니다. 예를 들어 로컬 파일 프로토콜 URL에는 엄격한 출처 검사가 적용되지 않습니다.
Electron을 사용하면 렌더러 프로세스로 콘텐츠를 로드하는 데 사용할 수 있는 사용자 지정 프로토콜을 등록할 수 있습니다. 사용자 지정 프로토콜은 보안 측면에서 HTTPS 프로토콜과 동일하게 작동하도록 구성할 수 있습니다. 우리는 이 접근 방식을 사용하여 콘텐츠를 제공하는 로컬 웹 서버를 실행해야 하는 부담을 피했습니다.
모든 렌더러 프로세스에 대해 사용자 지정 vscode-file 프로토콜을 도입함으로써 파일 프로토콜의 모든 사용을 중단할 수 있었습니다. HTTPS처럼 작동하도록 구성되었으며 웹용 VS Code가 실제로 작동하는 방식에 더 가까워졌음을 의미합니다.
코드 로더 조정
역사적으로 모든 TypeScript 코드는 AMD 모듈로 컴파일되고 수년간 유지 관리해 온 사용자 지정 로더로 로드되었습니다. AMD에서 벗어나 ESM을 채택할 계획이지만, 그 작업은 초기 단계에 있습니다.
우리의 코드 로더는 Node.js 및 웹 환경을 모두 지원하며, 실제 실행 환경을 파악하기 위해 잘 정의된 변수를 일부 프로빙합니다. 샌드박스 처리된 렌더러는 본질적으로 웹 환경과 같으므로 로더가 샌드박스를 지원하는 데 필요한 변경 사항은 거의 없었습니다.
이러한 변경 사항이 적용된 후 샌드박스 모드를 활성화한 VS Code의 초기 버전을 실행할 수 있었습니다. 그러나 렌더러 프로세스에서 Node.js 종속성을 아직 제거하지 않았기 때문에 빈 페이지가 표시되고 오류가 콘솔에 출력되었습니다.
채택을 돕는 도구
이제 VS Code를 샌드박스 활성화 상태로 실행할 수 있게 되었으므로 Node.js에 종속된 소스 코드에서 "샌드박스 준비" 코드로 전환을 더 쉽게 만들기 위한 도구에 투자하고 싶었습니다. 웹용 VS Code에 대한 투자를 통해 이미 웹 버전에 Node.js 코드가 배포되는 것을 방지하는 정적 분석 도구가 마련되어 있었습니다. 이 도구는 런타임 요구 사항을 가진 대상 환경 세트를 정의했습니다. 우리 도구는 허용되지 않는 대상 환경에서 Node.js 전역 개체(예: Buffer), Node.js API 또는 node 모듈의 사용을 감지하고 보고할 수 있습니다. 샌드박싱 작업을 위해 Node.js 사용을 전혀 허용하지 않는 새로운 대상 환경인 electron-sandbox를 추가했습니다. 이 환경으로 코드를 이동함으로써 코드를 점진적으로 샌드박스 준비 상태로 만들 수 있었습니다.
아래 스크린샷에서는 브라우저 대상 환경의 파일이 Node.js의 API에 종속되어 있음을 나타내는 경고 표시기가 편집기에 나타납니다. 경고는 빌드를 실패하게 하고 릴리스에 이 코드가 실수로 푸시되는 것을 방지합니다.

프로세스 탐색기 및 문제 보고자 유틸리티는 electron-sandbox 대상 요구 사항을 가장 먼저 준수한 것들 중 하나였습니다. 작업대 창이 채택을 완료하기 훨씬 전에 이러한 창을 완전히 샌드박스 처리된 상태로 실행할 수 있었습니다.
렌더러에서 프로세스 이동
이전 섹션에서 자세히 설명한 바와 같이 Node.js 기능의 일부를 다른 프로세스로 이동하고 IPC를 사용하여 작업을 예약하고 결과를 받는 것은 간단할 수 있습니다.
그러나 Node.js에 종속된 작업대의 일부 구성 요소는 더 복잡하며, 특히 자식 프로세스를 포크하는 구성 요소는 다음과 같습니다.
- 확장 호스트
- 통합 터미널
- 파일 감시
- 전체 텍스트 검색
- 작업 실행
- 디버깅
VS Code가 원격 시나리오에서 실행될 수 있다는 점을 고려할 때, 우리는 이미 일부 작업을 원격으로 수행하기 위한 메커니즘을 가지고 있었습니다. 즉, 검색, 디버깅 및 작업 실행입니다. 이러한 구성 요소는 코드가 있는 위치에 로컬로 실행되는 확장 호스트 프로세스 내에서 작동할 수 있습니다. 따라서 VS Code가 로컬로 실행되고 원격이 연결되지 않은 경우에도 이러한 자식 프로세스의 소유권을 렌더러 프로세스에서 확장 호스트로 이동할 수 있었습니다.
확장 호스트에 대해서는 더 야심 찬 계획이 있었습니다. 나중에 별도의 섹션에서 이러한 변경 사항을 다룰 것입니다. 이는 Electron에 새로운 "유틸리티 프로세스" API를 추가해야 했기 때문입니다.
통합 터미널과 파일 감시는 공유 프로세스의 자식 프로세스가 되도록 이동했습니다. 파일 감시 또는 통합 터미널이 필요한 모든 창은 메시지 포트를 통해 공유 프로세스와 통신하여 이러한 서비스를 얻었습니다.
아래 다이어그램은 렌더러 프로세스에서 샌드박스를 활성화했을 때의 2022년 말 프로세스 아키텍처를 보여줍니다. 모든 Node.js 프로세스는 공유 프로세스의 자식이거나 기본 프로세스의 유틸리티 프로세스가 되도록 이동했습니다. 메시지 포트는 모든 사용자 입력을 처리하는 기본 프로세스에 부담을 주지 않고 효율적인 직접 프로세스 간 통신에 사용됩니다.

Chromium의 코드 캐싱 조정
샌드박스 활성화가 성능 저하를 일으키지 않도록 하기 위해 측정했습니다. 시작부터 편집기에서 깜박이는 커서가 표시될 때까지 걸리는 시간과 V8 JavaScript 엔진이 주요 작업대 스크립트(약 11.5MB의 축소된 코드)를 로드, 구문 분석 및 실행하는 데 걸리는 중요한 시간을 측정했습니다. 업데이트가 설치되지 않는 한 매번 시작할 때마다 동일한 스크립트가 로드됩니다. 이 동작을 고려할 때 V8은 다음 로드 시간을 더 빠르게 하기 위해 디스크에 스크립트의 최적화된 버전을 저장할 수 있습니다. 코드 캐싱을 사용합니다.
Chromium 자체는 웹 페이지 로드 시간을 단축하기 위해 코드 캐싱을 사용합니다. V8 엔진에서 우리 솔루션과 동일한 최적화를 트리거하지만, Chromium 구현은 특정 기간 동안 자주 방문하는 웹 페이지에 대해서만 이 작업을 수행합니다. 우리는 애플리케이션이 웹 페이지가 아닌 데스크톱 애플리케이션이라는 점을 감안할 때 항상 코드 캐싱을 사용하는 솔루션을 원했습니다.
시작 시 코드 캐싱을 활성화했으며, 이는 시작 시간 개선을 위한 최고의 솔루션이 되었습니다. 불행히도 우리 솔루션은 Node.js에 의존했으며 샌드박스 처리된 렌더러 프로세스에서는 사용할 수 없었습니다.
Electron에서 코드 캐싱 옵션을 노출함으로써 bypassHeatCheck 옵션을 사용할 때 Chromium에서 코드 캐싱을 강제로 트리거할 수 있습니다. 또한 사용자가 최신 버전의 VS Code를 실행 중임을 감지할 때 이전에 생성된 코드 캐시를 삭제하는 추가 보호 계층을 추가했습니다.
새로운 Electron API: UtilityProcess
마지막이자 아마도 가장 복잡한 작업은 확장 호스트를 어디로 옮길지에 대한 솔루션을 찾는 것이었습니다. 공유 프로세스와 마찬가지로 통신은 Node.js 소켓을 통해 구현되었습니다. 창당 하나의 확장 호스트 프로세스가 있으며 확장은 필요한 만큼 많은 자식 프로세스를 자유롭게 생성할 수 있습니다.
파일 감시 및 통합 터미널처럼 확장 호스트를 공유 프로세스로 이동하는 것에 대해 생각했지만, 숨겨진 창이 아닌 호스트가 필요하지 않은 더 유연한 것을 구축할 기회를 잡아야 한다고 느꼈습니다.
이를 위해 샌드박스 처리된 렌더러에서 작동하지만 대부분의 현재 동작을 유지하는 강력하고 확장 가능한 솔루션을 원했습니다.
- 자식 프로세스 생성 지원이 포함된 격리된 프로세스
- 전체 Node.js 지원
- 샌드박스 처리된 프로세스와의 직접 IPC를 위해 메시지 포트 사용
당시 Electron은 이러한 요구 사항을 지원하는 API를 제공할 수 없었기 때문에 Electron에 새로운 유틸리티 프로세스 API를 기여했습니다. 이 API를 통해 확장 호스트를 렌더러 프로세스에서 기본 프로세스에서 생성된 유틸리티 프로세스로 이동할 수 있었습니다. 메시지 포트를 사용하여 사용자 입력을 처리하는 기본 프로세스와 같은 다른 프로세스에 영향을 주지 않고 렌더러와 확장 호스트 간에 직접 통신할 수 있었습니다.
Electron webview 요소에서 벗어나기
샌드박스 활성화에 반드시 필요한 것은 아니었지만, VS Code에서 Electron webview 태그의 사용을 재검토하고 VS Code가 웹에서 작동하는 방식과 더 가깝게 일치시키기 위해 iframe 태그로 교체했습니다. 두 태그 모두 작업대가 확장 프로그램의 신뢰할 수 없는 코드를 호스팅하면서 이러한 코드를 실행하는 영향으로부터 작업대를 격리한다는 점에서 유사합니다. 예를 들어 Markdown 파일의 미리보기를 열면 내장 Markdown 확장 프로그램에서 제공하는 이러한 요소에 내용이 렌더링됩니다.
대부분의 경우 webview 태그를 iframe 태그로 교체할 수 있었습니다. 그러나 iframe에는 누락된 한 가지 기능이 있었습니다. 바로 텍스트 검색을 수행하고 강조 표시하는 기능입니다. 이 기능은 Markdown 문서를 미리 볼 때 검색하는 것을 지원하는 데 중요했습니다. Chromium은 내부적으로 이 기능을 구현했지만, 웹 API로 노출되지 않아 사용할 수 없었습니다. 필요한 변경을 Electron에 노출하여 모든 webview 요소 사용을 중단할 수 있었습니다.
렌더러 프로세스 재사용 활성화
샌드박스 처리된 렌더러 프로세스의 한 가지 성능 이점은 Electron에서의 수명 주기 동작입니다. 전통적으로 렌더러 프로세스는 다른 URL로 탐색할 때마다 종료되고 다시 시작되었습니다. VS Code의 경우 작업 영역을 변경하거나 창을 다시 로드하면 렌더러 프로세스가 다시 생성되었으며, 이는 일부 환경 및 설정에서 느릴 수 있습니다.
샌드박스 처리된 렌더러 프로세스는 URL 탐색이 발생해도 계속 활성화됩니다. 다른 작업 영역을 열거나 현재 작업 영역을 다시 로드하는 것이 훨씬 빠릅니다. 그러나 이를 위해서는 렌더러 프로세스에서 실행되는 네이티브 Node.js 모듈이 컨텍스트 인식이 필요합니다. 샌드박싱을 활성화하기 위해 모든 네이티브 모듈을 렌더러 프로세스 밖으로 이동했지만, 샌드박싱을 활성화하기 전에 렌더러 프로세스 재사용을 테스트하고 싶었기 때문에 모든 네이티브 모듈을 컨텍스트 인식으로 만들었습니다.
모든 것을 종합
마지막 단계는 사용자 설정을 통해 샌드박스 모드를 조건부로 활성화하는 것이었습니다. 모든 사용자에게 샌드박스 모드를 활성화하는 대신 Insiders 에디션에서 검증할 시간을 주고 싶었습니다. window.experimental.useSandbox 설정을 통해 샌드박스는 Insiders에서 기본적으로 활성화되며 Stable에서도 활성화할 수 있습니다.
실험 인프라를 사용하여 2023년 초에 Stable 에디션에 샌드박스 활성화를 점진적으로 롤아웃할 계획입니다. 이를 통해 문제를 확인하면서 점점 더 많은 사용자에게 샌드박스 모드를 테스트하고 검증할 수 있습니다.
실험 단계가 끝나면 샌드박스 모드는 모든 사용자에게 기본적으로 활성화되고 비 샌드박스 모드는 제거됩니다. 향후 반복을 위해 몇 가지 작업이 계획되어 있습니다. 예를 들어, 공유 프로세스를 유틸리티 프로세스로 변환하려고 합니다. 이는 숨겨진 창이고 불필요하게 더 많은 리소스를 사용하기 때문입니다.
이것은 VS Code 팀 전체의 도움과 동기 부여 덕분에 가능했던 놀라운 여정이었습니다. 이러한 변경 사항을 점진적으로 배포하고 프로세스 샌드박싱을 요구하는 새로운 Electron 버전에 대비할 수 있다는 것은 매우 좋았습니다. 프로세스 아키텍처를 크게 개선하고 웹 모델과 더 가깝게 일치시켜 미래를 위한 강력한 기반을 만들 수 있었습니다.
사용된 용어
Electron은 VS Code 데스크톱이 지원되는 모든 플랫폼(Windows, macOS 및 Linux)에서 실행될 수 있도록 하는 주요 프레임워크입니다. Chromium과 브라우저 API, V8 JavaScript 엔진, Node.js API 및 플랫폼 통합 API를 결합하여 크로스 플랫폼 데스크톱 애플리케이션을 구축합니다.
이 블로그 게시물에서는 Electron 프로세스 샌드박싱을 "샌드박스"라고 간단히 부릅니다.
Chromium, 따라서 Electron이 제공하는 프로세스 모델을 이해하는 것이 중요합니다. 이 블로그 게시물에서는 다음 프로세스를 자주 참조합니다.
- 기본 프로세스 - 애플리케이션의 기본 진입점입니다.
- 렌더러 프로세스 - 사용자가 상호 작용할 수 있는 창입니다.
기본 프로세스는 항상 하나만 있지만 렌더러 프로세스는 열리는 창마다 생성됩니다. Electron 프로세스 모델 설명서와 이 Chrome Developers 블로그 게시물에서 프로세스 모델에 대해 더 자세히 알아볼 수 있습니다.
"공유 프로세스"는 Electron에만 국한된 것이 아니라 VS Code의 구현 세부 사항입니다. Node.js가 활성화된 숨겨진 Electron 창으로, 다른 모든 창이 확장 프로그램 설치와 같은 복잡한 작업을 수행하기 위해 통신할 수 있습니다.
"확장 호스트"는 설치된 모든 확장 프로그램을 렌더러 프로세스와 격리하여 실행하는 프로세스입니다. 열린 창마다 하나의 확장 호스트가 있습니다.
VS Code "작업대" 창은 사용자가 파일을 편집하거나, 검색하거나, 디버그하기 위해 상호 작용하는 기본 창입니다. 이 블로그 게시물에서는 간단히 "작업대"라고 합니다. 다른 창은 프로세스 탐색기 및 문제 보고자로, 도움말 메뉴에서 액세스할 수 있습니다.
"IPC"라는 용어는 프로세스 간 통신을 참조하는 데 사용됩니다. IPC는 한 프로세스가 다른 프로세스와 통신하는 방법입니다.
가장 최신 변경 사항을 사용자 집합에 테스트하기 위해 "Insiders"라고 하는 VS Code의 야간 빌드 버전을 출시합니다. VS Code 팀의 모든 사람은 Insiders 에디션을 사용하며 여러분도 시도해 보고 문제를 보고해 주시기를 바랍니다.
행복한 코딩 되세요!
Benjamin Pasero, @BenjaminPasero