Spec-Zone.ru › Deno 2

Безопасность и разрешения

Deno по умолчанию безопасен. Если вы не включите его, программа, запущенная с помощью Deno, не имеет доступа к чувствительным API, таким как доступ к файловой системе, сетевое подключение или доступ к среде. Вам необходимо явно предоставить доступ к этим ресурсам с помощью флагов командной строки или с помощью запроса разрешения на выполнение. Это существенное отличие от Node, где зависимости автоматически получают полный доступ ко всем системным вводу-выводу, что может потенциально вносить скрытые уязвимости в ваш проект.

Перед использованием Deno для выполнения полностью недоверенного кода ознакомьтесь с разделом о выполнении недоверенного кода ниже.

Основные принципы

Прежде чем перейти к деталям разрешений, важно понять основные принципы модели безопасности Deno:

  • По умолчанию нет доступа к вводу-выводу: Код, выполняющийся в среде Deno, не имеет доступа к чтению или записи произвольных файлов в файловой системе, к отправке сетевых запросов или открытию сетевых слушателей, к доступу к переменным среды или запуску дочерних процессов.
  • Нет ограничений на выполнение кода на одном уровне привилегий: Deno позволяет выполнять любой код (JS/TS/Wasm) с помощью различных методов, включая eval, new Function, динамический импорт и веб-рабочие процессы на одном уровне привилегий с небольшими ограничениями относительно того, откуда происходит код (сеть, npm, JSR и т. д.).
  • Несколько вызовов одного приложения могут совместно использовать данные: Deno предоставляет механизм для совместного использования данных несколькими вызовами одного приложения с помощью встроенных API кэширования и хранения KV. Разные приложения не могут видеть данные друг друга.
  • Весь код, выполняемый в одном потоке, имеет один и тот же уровень привилегий: Весь код, выполняемый в одном потоке, имеет один и тот же уровень привилегий. Разные модули не могут иметь разные уровни привилегий в рамках одного потока.
  • Код не может повышать свои привилегии без согласия пользователя: Код, выполняющийся в среде Deno, не может повышать свои привилегии без явного согласия пользователя на повышение привилегий через интерактивный запрос или флаг вызова.
  • Начальная статическая графа модулей может импортировать локальные файлы без ограничений: Все файлы, импортированные в начальной статической графе модулей, могут импортироваться без ограничений, даже если для этого файла не предоставлено явное разрешение на чтение. Это не относится к динамическому импорту модулей.

Эти основные принципы предназначены для создания среды, в которой пользователь может выполнять код с минимальным риском повреждения хост-машины или сети. Модель безопасности проста в понимании и обеспечивает четкое разделение обязанностей между средой выполнения и кодом, выполняющимся в ней. Модель безопасности поддерживается средой выполнения Deno и не зависит от базовой операционной системы.

Разрешения

По умолчанию доступ к большинству системных операций ввода-вывода запрещен. Некоторые операции ввода-вывода разрешены в ограниченном объеме, даже по умолчанию. Они описаны ниже.

Чтобы включить эти операции, пользователь должен явно предоставить разрешение среде выполнения Deno. Это делается путем передачи флагов --allow-read, --allow-write, --allow-net, --allow-env, и --allow-run к команде deno.

Во время выполнения скрипта пользователь также может явно предоставить разрешение на доступ к определенным файлам, каталогам, сетевым адресам, переменным среды и дочерним процессам при запросе среды выполнения. Запросы не отображаются, если stdout/stderr не являются терминалом, или при передаче флага --no-prompt команде deno.

Пользователи также могут явно запретить доступ к определенным ресурсам, используя флаги --deny-read, --deny-write, --deny-net, --deny-env, и --deny-run. Эти флаги имеют приоритет над флагами разрешения. Например, если вы разрешаете сетевой доступ, но запрещаете доступ к определенному домену, флаг запрета будет иметь приоритет.

Deno также предоставляет флаг --allow-all, который предоставляет все разрешения скрипту. Это отключает защищенную среду выполнения, и его следует использовать с осторожностью. У --allow-all те же свойства безопасности, что и при запуске скрипта в Node.js (т. е. нет).

Определение: -A, --allow-all

deno run -A script.ts
deno run --allow-all script.ts

Доступ к файловой системе

По умолчанию выполняемый код не может читать или записывать произвольные файлы в файловой системе. Это включает перечисление содержимого каталогов, проверку существования файла и открытие или подключение к Unix-сокетному соединению.

Доступ к чтению файлов предоставляется с помощью флага --allow-read, а доступ к записи файлов — с помощью флага --allow-write. Эти флаги могут быть указаны со списком путей для разрешения доступа к определенным файлам или каталогам.

Определение: --allow-read[=<PATH>...] или -R[=<PATH>...]

# Allow all reads from file system
deno run -R script.ts
# or 
deno run --allow-read script.ts

# Allow reads from file foo.txt and bar.txt only
deno run --allow-read=foo.txt,bar.txt script.ts

Определение: --deny-read[=<PATH>...]

# Allow reading files in /etc but disallow reading /etc/hosts
deno run --allow-read=/etc --deny-read=/etc/hosts script.ts

# Deny all read access to disk, disabling permission prompts for reads.
deno run --deny-read script.ts

Определение: --allow-write[=<PATH>...] или -W[=<PATH>...]

# Allow all writes to file system
deno run -W script.ts
# or 
deno run --allow-write script.ts

# Allow writes to file foo.txt and bar.txt only
deno run --allow-write=foo.txt,bar.txt script.ts

Определение: --deny-write[=<PATH>...]

# Allow reading files in current working directory 
# but disallow writing to ./secrets directory.
deno run --allow-write=./ --deny-write=./secrets script.ts

# Deny all write access to disk, disabling permission prompts.
deno run --deny-write script.ts

Некоторые API в Deno реализованы с использованием операций с файловой системой внутри, даже если они не предоставляют прямой доступ к чтению/записи определенных файлов. Эти API читают и записывают на диск, но не требуют явных разрешений на чтение/запись. Некоторые примеры таких API:

  • localStorage
  • Deno KV
  • caches
  • Blob

Поскольку эти API реализованы с использованием операций с файловой системой, пользователи могут использовать их для потребления системных ресурсов, таких как дисковое пространство, даже если у них нет прямого доступа к файловой системе.

При загрузке модулей Deno может загружать файлы с диска. Иногда это требует явных разрешений, а иногда разрешено по умолчанию:

  • Все файлы, импортированные из модуля входа в таком виде, чтобы их можно было статически проанализировать, разрешается читать по умолчанию. Это включает статические import инструкции и динамические import() вызовы, где аргумент представляет собой строковую литерал, указывающую на конкретный файл или каталог файлов. Полный список файлов в этом списке можно вывести с помощью deno info <entrypoint>.
  • Файлы, которые динамически импортируются таким образом, что их нельзя статически проанализировать, требуют разрешения на чтение во время выполнения.
  • Файлы внутри каталога node_modules/ разрешено читать по умолчанию.

При получении модулей из сети или при транспиляции кода из TypeScript в JavaScript Deno использует файловую систему в качестве кэша. Это означает, что ресурсы файловой системы, такие как дисковое пространство, могут быть использованы Deno, даже если пользователь явно не предоставил разрешения на чтение/запись.

Доступ к сети

По умолчанию выполняемый код не может отправлять сетевые запросы, открывать сетевые слушатели или выполнять разрешение DNS. Это включает отправку HTTP-запросов, открытие TCP/UDP-сокетных соединений и прослушивание входящих подключений по TCP или UDP.

Доступ к сети предоставляется с помощью флага --allow-net. Этот флаг может быть указан со списком IP-адресов или доменных имен для разрешения доступа к определенным сетевым адресам.

Определение: --allow-net[=<IP_OR_HOSTNAME>...] или -N[=<IP_OR_HOSTNAME>...]

# Allow network access
deno run -N script.ts
# or
deno run --allow-net script.ts

# Allow network access to github.com and jsr.io
deno run --allow-net=github.com,jsr.io script.ts

# A hostname at port 80:
deno run --allow-net=example.com:80 script.ts

# An IPv4 address on port 443
deno run --allow-net=1.1.1.1:443 script.ts

# An IPv6 address, all ports allowed
deno run --allow-net=[2606:4700:4700::1111] script.ts

Определение: --deny-net[=<IP_OR_HOSTNAME>...]

# Allow access to network, but deny access 
# to github.com and jsr.io
deno run --allow-net --deny-net=github.com,jsr.io script.ts

# Deny all network access, disabling permission prompts.
deno run --deny-net script.ts

При загрузке модулей Deno может загружать модули из сети. По умолчанию Deno позволяет загружать модули из следующих расположений с помощью статических и динамических импортов без необходимости явного доступа к сети:

  • https://deno.land/
  • https://jsr.io/
  • https://esm.sh/
  • https://raw.githubusercontent.com
  • https://gist.githubusercontent.com

Эти расположения являются доверенными общедоступными реестрами, которые, как ожидается, не будут обеспечивать утечку данных через пути URL. Вы можете добавить больше доверенных реестров, используя флаг --allow-imports.

Кроме того, Deno разрешает импорт любых пакетов NPM через npm: спецификаторы.

Deno также отправляет запросы к https://dl.deno.land/ не более одного раза в день, чтобы проверить наличие обновлений Deno CLI. Это можно отключить, используя переменную среды DENO_NO_UPDATE_CHECK=1.

Переменные среды

По умолчанию выполняемый код не может читать или записывать переменные среды. Это включает чтение переменных среды и установку новых значений.

Доступ к переменным среды предоставляется с помощью флага --allow-env. Этот флаг может быть указан со списком переменных среды для разрешения доступа к определенным переменным среды. Начиная с версии Deno v2.1, вы теперь можете указать подстановочные знаки суффиксов для разрешения «ограниченного» доступа к переменным среды.

Определение: --allow-env[=<VARIABLE_NAME>...] или -E[=<VARIABLE_NAME>...]

# Allow access to all environment variables
deno run -E script.ts
# or
deno run --allow-env script.ts

# Allow HOME and FOO environment variables
deno run --allow-env=HOME,FOO script.ts

# Allow access to all environment variables starting with AWS_
deno run --allow-env="AWS_*" script.ts

Определение: --deny-env[=<VARIABLE_NAME>...]

# Allow all environment variables except 
# AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
deno run \
  --allow-env \
  --deny-env=AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY \
  script.ts

# Deny all access to env variables, disabling permission prompts.
deno run --deny-env script.ts

Примечание для пользователей Windows: переменные среды нечувствительны к регистру в Windows, поэтому Deno также сопоставляет их без учета регистра (только в Windows).

Deno считывает определенные переменные среды при запуске, такие как DENO_DIR и NO_COLOR (см. полный список).

Значение переменной среды NO_COLOR видно для всего кода, выполняемого в среде Deno, независимо от того, разрешен ли коду доступ к чтению переменных среды.

Информация о системе

По умолчанию выполняемый код не может получить доступ к информации о системе, такой как версия операционной системы, время работы системы, средняя нагрузка, сетевые интерфейсы и информация о системной памяти.

Доступ к информации о системе предоставляется с помощью флага --allow-sys. Этот флаг может быть указан со списком разрешенных интерфейсов из следующего списка: hostname, osRelease, osUptime, loadavg, networkInterfaces, systemMemoryInfo, uid, и gid. Эти строки соответствуют функциям в пространстве имен Deno, которые предоставляют информацию об ОС, например, Deno.systemMemoryInfo.

Определение: --allow-sys[=<API_NAME>...] или -S[=<API_NAME>...]

# Allow all system information APIs
deno run -S script.ts
# or
deno run --allow-sys script.ts

# Allow systemMemoryInfo and osRelease APIs
deno run --allow-sys="systemMemoryInfo,osRelease" script.ts

Определение: --deny-sys[=<API_NAME>...]

# Allow accessing all system information but "networkInterfaces"
deno run --allow-sys --deny-sys="networkInterfaces" script.ts

# Deny all access to system information, disabling permission prompts.
deno run --deny-sys script.ts

Дочерние процессы

Код, выполняющийся внутри среды Deno, по умолчанию не может запускать дочерние процессы, так как это нарушает принцип, согласно которому код не может повышать свои привилегии без согласия пользователя.

Deno предоставляет механизм для запуска дочерних процессов, но это требует явного разрешения от пользователя. Это делается с помощью флага --allow-run.

Любые дочерние процессы, запущенные в вашей программе, работают независимо от разрешений, предоставленных родительскому процессу. Это означает, что дочерние процессы могут получить доступ к системным ресурсам независимо от разрешений, предоставленных процессу Deno, который их запустил. Это часто называется эскалацией привилегий.

По этой причине, тщательно обдумайте, хотите ли вы предоставить программе --allow-run доступ: это фактически аннулирует защищённую зону Deno. Если вам действительно нужно запустить определённый исполняемый файл, вы можете снизить риск, ограничив, какие программы может запускать процесс Deno, передав конкретные имена исполняемых файлов флагу --allow-run.

Определение: --allow-run[=<PROGRAM_NAME>...]

# Allow running all subprocesses
deno run --allow-run script.ts

# Allow running "curl" and "whoami" subprocesses
deno run --allow-run="curl,whoami" script.ts
Внимание

Вероятно, вы никогда не захотите использовать --allow-run=deno, если родительский процесс не имеет --allow-all, так как возможность запуска дочернего процесса deno означает, что сценарий может запустить другой процесс deno с полными правами.

Определение: --deny-run[=<PROGRAM_NAME>...]

# Allow running running all programs, but "whoami" and "ps".
deno run --allow-run --deny-run="whoami,ps" script.ts

# Deny all access for spawning subprocessing, disabling
# permission prompts.
deno run --deny-run script.ts

По умолчанию пакеты npm не будут выполнять свои скрипты пост-установки во время установки (как и с deno install), так как это позволило бы произвольному выполнению кода. При запуске с флагом --allow-scripts скрипты пост-установки пакетов npm будут выполняться как дочерние процессы.

FFI

Deno предоставляет механизм для выполнения кода, написанного на других языках, таких как Rust, C или C++, изнутри среды выполнения Deno. Это делается с помощью API Deno.dlopen, который может загружать динамические библиотеки и вызывать функции из них.

По умолчанию выполнение кода не может использовать API Deno.dlopen, так как это нарушило бы принцип, что код не может повышать свои привилегии без согласия пользователя.

Помимо Deno.dlopen, FFI также может использоваться через нативные плагины Node-API (NAPI). Они также по умолчанию запрещены.

И нативные плагины Deno.dlopen и NAPI требуют явного разрешения, используя флаг --allow-ffi. Этот флаг может быть указан со списком файлов или каталогов, чтобы разрешить доступ к определённым динамическим библиотекам.

Как и дочерние процессы, динамические библиотеки не выполняются в защищённой зоне и поэтому не имеют тех же ограничений безопасности, что и процесс Deno, в который они загружаются. Поэтому используйте с большой осторожностью.

Определение: --allow-ffi[=<PATH>...]

# Allow loading dynamic all libraries
deno run --allow-ffi script.ts

# Allow loading dynamic libraries from a specific path
deno run --allow-ffi=./libfoo.so script.ts

Определение: --deny-ffi[=<PATH>...]

# Allow loading all dynamic libraries, but ./libfoo.so
deno run --allow-ffi --deny-ffi=./libfoo.so script.ts

# Deny loading all dynamic libraries, disabling permission prompts.
deno run --deny-ffi script.ts

Импорт из веб

Разрешить импорт кода с веб-сайтов. По умолчанию Deno ограничивает хосты, с которых можно импортировать код. Это справедливо как для статических, так и для динамических импортов.

Если вы хотите динамически импортировать код, используя API import() или new Worker(), необходимо предоставить дополнительные разрешения. Импорт из локальной файловой системы требует --allow-read, но Deno также позволяет импортировать из http: и https: URL-адресов. В этом случае вам нужно указать явный флаг --allow-import:

# allow importing code from `https://example.com`
$ deno run --allow-import=example.com main.ts

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

  • deno.land
  • esm.sh
  • jsr.io
  • cdn.jsdelivr.net
  • raw.githubusercontent.com
  • gist.githubusercontent.com

Импорт разрешён только с использованием HTTPS

Этот список разрешённых хостов применяется по умолчанию для статических импортов и по умолчанию для динамических импортов, если указан флаг --allow-import.

# allow dynamically importing code from `https://deno.land`
$ deno run --allow-import main.ts

Обратите внимание, что указание списка разрешённых хостов для --allow-import переопределит список по умолчанию.

Выполнение кода

Deno не устанавливает никаких ограничений на выполнение кода на том же уровне привилегий. Это означает, что код, выполняемый в среде выполнения Deno, может использовать eval, new Function, или даже динамический импорт или веб-рабочие процессы для выполнения **произвольного** кода с тем же уровнем привилегий, что и код, который вызвал eval, new Function, или динамический импорт или веб-рабочий процесс.

Этот код может размещаться в сети, находиться в локальном файле (если предоставлены права на чтение) или храниться как обычный текст в строке внутри кода, который вызвал eval, new Function, или динамический импорт или веб-рабочий процесс.

Выполнение недоверенного кода

Хотя Deno предоставляет функции безопасности, предназначенные для защиты хост-машины и сети от вреда, недоверенный код всё ещё представляет опасность. При выполнении недоверенного кода важно иметь не одну линию защиты. Ниже приведены некоторые рекомендации для выполнения недоверенного кода, и мы рекомендуем использовать все эти рекомендации при выполнении произвольного недоверенного кода:

  • Запустите deno с ограниченными правами и определите заранее, какой код фактически нужно выполнить (и предотвратите загрузку большего объёма кода, используя --frozen файл блокировки и --cached-only).
  • Используйте механизмы изоляции ОС, такие как chroot, cgroups, seccomp и т.д.
  • Используйте защищённую среду, например, виртуальную машину или MicroVM (gVisor, Firecracker и т.д.).

© 2018–2024 the Deno authors
Licensed under the MIT License.
https://docs.deno.com/runtime/fundamentals/security

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API