パーミッション
パーミッションは、Node.js プロセスがアクセスできるシステムリソース、またはプロセスがそれらのリソースに対して実行できるアクションを制御するために使用できます。
- プロセスベースのパーミッションは、Node.js プロセスのリソースへのアクセスを制御します。リソースは完全に許可または拒否するか、それに関連するアクションを制御できます。たとえば、ファイルシステムの読み取りを許可しながら、書き込みを拒否できます。この機能は、悪意のあるコードから保護するものではありません。Node.js のセキュリティポリシーに従って、Node.js は実行するように要求されたコードをすべて信頼します。
パーミッションモデルは、「シートベルト」アプローチを実装しており、信頼できるコードが、アクセスが明示的に許可されていないファイルの変更やリソースの使用を意図せずに実行することを防ぎます。悪意のあるコードが存在する場合、セキュリティ保証を提供するものではありません。悪意のあるコードは、パーミッションモデルをバイパスし、パーミッションモデルによって課せられた制限なしに任意のコードを実行できます。
潜在的なセキュリティ脆弱性を見つけた場合は、セキュリティポリシーを参照してください。
プロセスベースのパーミッション
パーミッションモデル
Node.js パーミッションモデルは、実行中に特定のリソースへのアクセスを制限するためのメカニズムです。API はフラグ--permission
の背後に存在し、有効にすると、利用可能なすべてのパーミッションへのアクセスが制限されます。
利用可能なパーミッションは、--permission
フラグによって文書化されています。
--permission
を使用して Node.js を起動すると、fs
モジュールによるファイルシステムへのアクセス、プロセスの生成、node:worker_threads
の使用、ネイティブアドオンの使用、WASI の使用、およびランタイムインスペクターの有効化が制限されます。
$ 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'
}
2
3
4
5
6
7
8
プロセスの生成とワーカスレッドの作成へのアクセスを許可するには、それぞれ--allow-child-process
と--allow-worker
を使用します。
パーミッションモデルを使用する場合にネイティブアドオンを許可するには、--allow-addons
フラグを使用します。WASI の場合は、--allow-wasi
フラグを使用します。
ランタイム API
--permission
フラグでパーミッションモデルを有効にすると、process
オブジェクトに新しいプロパティpermission
が追加されます。このプロパティには、1 つの関数が含まれています。
permission.has(scope[, reference])
ランタイムでパーミッションを確認するための API 呼び出し(permission.has()
)
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
2
3
4
5
ファイルシステムのパーミッション
パーミッションモデルは、デフォルトでnode:fs
モジュールによるファイルシステムへのアクセスを制限します。node:sqlite
モジュールなど、他の手段でユーザーがファイルシステムにアクセスできないことを保証するものではありません。
ファイルシステムへのアクセスを許可するには、--allow-fs-read
と--allow-fs-write
フラグを使用します。
$ node --permission --allow-fs-read=* --allow-fs-write=* index.js
Hello world!
2
両方のフラグの有効な引数は次のとおりです。
*
- すべてのFileSystemRead
またはFileSystemWrite
操作をそれぞれ許可します。- カンマ(
,
)で区切られたパス - それぞれ一致するFileSystemRead
またはFileSystemWrite
操作のみを許可します。
例:
--allow-fs-read=*
- すべてのFileSystemRead
操作を許可します。--allow-fs-write=*
- すべてのFileSystemWrite
操作を許可します。--allow-fs-write=/tmp/
-/tmp/
フォルダへのFileSystemWrite
アクセスを許可します。--allow-fs-read=/tmp/ --allow-fs-read=/home/.gitignore
-/tmp/
フォルダと/home/.gitignore
パスのFileSystemRead
アクセスを許可します。
ワイルドカードもサポートされています。
--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/\*
権限モデルの制約
このシステムを使用する前に知っておく必要がある制約事項があります。
モデルは子ノードプロセスまたはワーカスレッドに継承されません。
権限モデルを使用する場合、以下の機能が制限されます。
- ネイティブモジュール
- 子プロセス
- ワーカースレッド
- インスペクタプロトコル
- ファイルシステムアクセス
- WASI
権限モデルは Node.js 環境の設定後に初期化されます。しかし、
--env-file
や--openssl-config
などの特定のフラグは、環境初期化前にファイルを読み取るように設計されています。そのため、このようなフラグは権限モデルのルールに従いません。v8.setFlagsFromString
を介して実行時に設定できる V8 フラグにも同じことが当てはまります。権限モデルが有効になっている場合、実行時に OpenSSL エンジンを要求することはできません。これにより、組み込みの crypto、https、および tls モジュールに影響します。
権限モデルが有効になっている場合、実行時ロード可能な拡張機能を読み込むことはできません。これにより、sqlite モジュールに影響します。
node:fs
モジュールを介して既存のファイルディスクリプタを使用すると、権限モデルをバイパスします。
制限事項と既知の問題
- シンボリックリンクは、アクセスが許可されたパスの集合の外側の場所にも追従されます。相対的なシンボリックリンクは、任意のファイルやディレクトリへのアクセスを許可する可能性があります。権限モデルを有効にしてアプリケーションを起動する際には、アクセスが許可されたパスに相対的なシンボリックリンクが含まれていないことを確認する必要があります。