Перейти к содержанию

Разрешения

latest

Разрешения позволяют контролировать, к каким системным ресурсам имеет доступ процесс Node.js и какие действия с этими ресурсами он может выполнять.

  • Разрешения на уровне процесса управляют доступом процесса Node.js к ресурсам. Ресурс можно полностью разрешить или запретить, либо ограничить отдельные действия. Например, можно разрешить чтение файловой системы и запретить запись. Эта возможность не защищает от злонамеренного кода. Согласно политике безопасности Node.js, движок доверяет любому коду, который ему предлагают выполнить.

Модель разрешений реализует подход «ремня безопасности»: она не даёт доверенному коду случайно менять файлы или использовать ресурсы, к которым доступ явно не выдан. Она не даёт гарантий безопасности при наличии злонамеренного кода. Злонамеренный код может обойти модель разрешений и выполнить произвольный код без наложенных ограничений.

Если вы обнаружили потенциальную уязвимость безопасности, ознакомьтесь с нашей политикой безопасности.

Разрешения на уровне процесса

Модель разрешений

Стабильность: 2 – Стабильная

API является удовлетворительным. Совместимость с npm имеет высший приоритет и не будет нарушена, кроме случаев явной необходимости.

Модель разрешений Node.js — механизм ограничения доступа к отдельным ресурсам во время выполнения. API доступно за флагом --permission: при его включении доступ ко всем перечисленным разрешениям ограничивается.

Список доступных разрешений описан в документации флага --permission.

При запуске Node.js с --permission доступ к файловой системе через модуль fs, к сети, создание дочерних процессов, использование node:worker_threads, нативных аддонов, WASI, а также включение инспектора выполнения будут ограничены (слушатель SIGUSR1 создаваться не будет).

1
2
3
4
5
6
7
8
$ node --permission index.js

Error: Access to this API has been restricted
    at node:internal/main/run_main_module:23:47 {
  code: 'ERR_ACCESS_DENIED',
  permission: 'FileSystemRead',
  resource: '/home/user/index.js'
}

Разрешить создание дочернего процесса и потоков worker можно с помощью --allow-child-process и --allow-worker соответственно.

Чтобы разрешить сетевой доступ, используйте --allow-net; для нативных аддонов при включённой модели разрешений — флаг --allow-addons. Для WASI — флаг --allow-wasi.

API времени выполнения

При включении модели разрешений через флаг --permission к объекту process добавляется свойство permission. Оно содержит одну функцию:

permission.has(scope[, reference])

Вызов для проверки разрешений во время выполнения (permission.has())

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
process.permission.has('fs.write'); // true
process.permission.has(
    'fs.write',
    '/home/rafaelgss/protected-folder'
); // true

process.permission.has('fs.read'); // true
process.permission.has(
    'fs.read',
    '/home/rafaelgss/protected-folder'
); // false

Разрешения файловой системы

По умолчанию модель разрешений ограничивает доступ к файловой системе через модуль node:fs. Она не гарантирует, что пользователь не сможет обратиться к файловой системе другими путями, например через модуль node:sqlite.

Чтобы разрешить доступ к файловой системе, используйте флаги --allow-fs-read и --allow-fs-write:

1
2
$ node --permission --allow-fs-read=* --allow-fs-write=* index.js
Hello world!

По умолчанию точки входа приложения включаются в список разрешённых чтений из файловой системы. Например:

1
$ node --permission index.js
  • index.js будет включён в список разрешённых чтений из файловой системы
1
$ node -r /path/to/custom-require.js --permission index.js.
  • /path/to/custom-require.js будет включён в список разрешённых чтений из файловой системы.
  • index.js будет включён в список разрешённых чтений из файловой системы.

Допустимые аргументы для обоих флагов:

  • * — разрешить все операции FileSystemRead или FileSystemWrite соответственно.
  • Относительные пути относительно текущего рабочего каталога.
  • Абсолютные пути.

Примеры:

  • --allow-fs-read=* — разрешит все операции FileSystemRead.
  • --allow-fs-write=* — разрешит все операции FileSystemWrite.
  • --allow-fs-write=/tmp/ — разрешит FileSystemWrite для каталога /tmp/.
  • --allow-fs-read=/tmp/ --allow-fs-read=/home/.gitignore — разрешит FileSystemRead для каталога /tmp/ и пути /home/.gitignore.

Поддерживаются и шаблоны:

  • --allow-fs-read=/home/test* разрешит чтение всего, что совпадает с шаблоном, например /home/test/file1 или /home/test2

После символа шаблона (*) остальные символы в шаблоне игнорируются. Например, /home/*.js ведёт себя аналогично /home/*.

При инициализации модели разрешений к указанному каталогу автоматически добавляется шаблон (*), если такой каталог существует. Например, если существует /home/test/files, он будет обработан как /home/test/files/*. Если каталога нет, шаблон не добавляется, и доступ ограничен путём /home/test/files. Если нужно разрешить доступ к каталогу, которого ещё нет, явно укажите шаблон: /my-path/folder-do-not-exist/*.

Поддержка файла конфигурации

Помимо передачи флагов разрешений в командной строке, их можно задать в файле конфигурации Node.js при использовании экспериментального флага --experimental-config-file. Опции разрешений должны находиться в объекте верхнего уровня permission.

Пример node.config.json:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
    "permission": {
        "allow-fs-read": ["./foo"],
        "allow-fs-write": ["./bar"],
        "allow-child-process": true,
        "allow-worker": true,
        "allow-net": true,
        "allow-addons": false
    }
}

Если в файле конфигурации присутствует пространство имён permission, Node.js автоматически включает флаг --permission. Запуск:

1
$ node --experimental-default-config-file app.js

Использование модели разрешений с npx

Если вы запускаете скрипт Node.js через npx, модель разрешений можно включить, передав флаг --node-options. Например:

1
npx --node-options="--permission" package-name

Так задаётся переменная окружения NODE_OPTIONS для всех процессов Node.js, запущенных npx, без влияния на сам процесс npx.

Ошибка FileSystemRead при использовании npx

Приведённая выше команда, скорее всего, вызовет ошибку недопустимого доступа FileSystemRead, потому что Node.js нужен доступ на чтение файловой системы, чтобы найти и выполнить пакет. Чтобы этого избежать:

  1. Глобально установленный пакет Выдайте доступ на чтение глобального каталога node_modules:

    1
    npx --node-options="--permission --allow-fs-read=$(npm prefix -g)" package-name
    
  2. Кэш npx Если пакет ставится временно или используется кэш npx, выдайте доступ на чтение каталога кэша npm:

    1
    npx --node-options="--permission --allow-fs-read=$(npm config get cache)" package-name
    

Любые аргументы, которые вы обычно передаёте node (например, флаги --allow-*), можно также передать через --node-options. Это упрощает настройку разрешений при работе с npx.

Ограничения модели разрешений

Перед использованием учтите следующее:

  • Модель не наследуется в поток worker.
  • При включённой модели разрешений ограничиваются:
    • нативные модули;
    • сеть;
    • дочерние процессы;
    • потоки Worker;
    • протокол инспектора;
    • доступ к файловой системе;
    • WASI.
  • Модель разрешений инициализируется после подготовки окружения Node.js. Однако некоторые флаги, например --env-file или --openssl-config, читают файлы до инициализации окружения. Поэтому к таким флагам правила модели разрешений не применяются. То же относится к флагам V8, задаваемым во время выполнения через v8.setFlagsFromString.
  • Движки OpenSSL нельзя подключать во время выполнения при включённой модели разрешений; это затрагивает встроенные модули crypto, https и tls.
  • Расширения с загрузкой во время выполнения нельзя загрузить при включённой модели разрешений; это затрагивает модуль sqlite.
  • Использование уже открытых дескрипторов файлов через модуль node:fs обходит модель разрешений.

Ограничения и известные проблемы

  • Символические ссылки разрешаются даже к расположениям вне набора путей, на которые выдан доступ. Относительные символические ссылки могут открыть доступ к произвольным файлам и каталогам. Запуская приложения с включённой моделью разрешений, убедитесь, что среди путей с выданным доступом нет относительных символических ссылок.

Комментарии