서론

Node.js 는 V8과 libuv 위에 얹힌 C++ 런타임이지만 레포를 보면 JS 파일(lib/*.js, lib/internal/*)도 가지고 있다.
이 JS 코드들은 Node의 모듈- JS 코드 간 인터페이스 역할을 하는데, 유저 코드와 동일한 환경에서 함께 실행되기 때문에 악의 또는 실수에 의해 오염될 가능성도 있다! Node.js가 JS 객체를 보호하기 위한 방법을 알아보았다.

worker_threads.js. process._eval을 덮어쓴다면..?


1. Symbol로 내부 상태 은닉

  • Node 내부 객체는 Symbol을 이용해 비공개 상태를 저장한다.
  • Symbol 키는 열거 불가능하고 충돌 위험이 없다.

_http_client.js

2. 클로저로 모듈 스코프 격리

  • Node.js는 각 모듈을 로드할 때, 해당 코드를 자동으로 함수 스코프로 감싸 실행한다.
  • 이 함수는 즉시 실행되어 모듈의 내용을 독립된 클로저(closure) 로 감싼다.덕분에 파일 단위로 독립된 렉시컬 환경(lexical environment) 이 형성되며,각 모듈의 내부 변수나 헬퍼 함수는 외부에서 직접 접근할 수 없다.

출처: https://nodejs.org/api/modules.html#the-module-wrapper

It keeps top-level variables (defined with var, const, or let) scoped to the module rather than the global object.

 

require('XXX')
 └─ Module.require()
      └─ Module._load()
           └─ Module._extensions['.js'](module, filename)

                 └─Module._compile

                        └─ wrapSafe

                             └─Module.wrap

loader.js

3. Primordials로 원본 내장 객체 보존

  • Node는 부팅 시 Array.prototype, Object, Promise 등
    원본 내장 객체의 복사본을 따로 저장한다.(lib/internal/per_context/primordials.js)
  • 이후 core 모듈들은 이 복사본을 직접 사용한다.
  • 덕분에 유저가 Array.prototype.push를 덮어써도Node 내부는 영향을 받지 않는다.

primordials.js 정의들
this 없이 함수를 바인딩

+ Recent posts