JupyterLab: JupyterLabにおけるクロスサイトスクリプティング(XSS)脆弱性(システムクリップボードからコピー&ペーストされたノートブックのセル経由)
## 概要
JupyterLab 4.5.0では、システムクリップボードを介してセルのコピー&ペースト機能が有効になりました。ペースト機能は、クリップボードのテキストをセルのJSONとして解析し、セルの挿入時に`metadata.trusted`をクリアしないため、悪意のあるコードが自身の出力を信頼済みとして宣言することができます。JupyterLabは信頼済みの出力をサニタイズせず、その中に含まれる`<script>`要素を実行するため、セルのペーストによって攻撃者のJavaScriptがJupyterLabのオリジンで実行されます。一方、`"trusted": false`が設定されたペイロードはサニタイズされます。
```json
[
{
"cell_type": "code",
"execution_count": null,
"source": "",
"metadata": { "trusted": true },
"outputs": [
{
"output_type": "display_data",
"metadata": {},
"data": { "text/html": "<script>/* ペースト時に実行される */</script>" }
}
]
}
]
```
以下のすべての条件が満たされる場合に、ユーザーは影響を受ける可能性があります。
- JupyterLab 4.5.0から4.6.3、またはNotebook 7.5以降などの、それを含むアプリケーションを使用している。
- 4.5.2以降のバージョンを使用している場合、`useSystemClipboardForCells`が有効になっている(デフォルトでは無効。4.5.2以降はデフォルトで無効、4.5.0および4.5.1では常に有効で、無効化するオプションはない)。
- 攻撃者が制御するテキストがクリップボードに存在している状態で、ペーストコマンド(コンテキストメニュー、コマンドパレット、ショートカットなど)を実行する。
- `pasteCodeCellsWithoutOutput`がオフになっている(デフォルト)。これにより、ペーストされたセルは自身の出力を保持します。
### 影響
このスクリプトは、認証されたユーザーと同じオリジンとセッションでJupyterLabのページ内で実行されるため、そのユーザーとしてJupyter Server REST APIを呼び出すことができます。これにより、サーバーのルートディレクトリにあるすべてのファイルへの読み書き、カーネルの起動とコードの実行、およびターミナル機能が有効な場合のターミナルの起動が可能になります。このスクリプトは、ユーザーが何も実行しなくても、ペースト時に実行されます。
コードセルでのみ、このような方法でスクリプトを実行できます。Markdownセルやプレーンテキストセルは常に安全化されます。これは、[信頼に関するドキュメント](https://jupyterlab.readthedocs.io/en/latest/user/notebook.html#trust)に記載されています。
攻撃者がJupyterLabのアカウントやサーバーへのアクセスを必要とするのは、ユーザーのクリップボードの内容をコピーする瞬間に限ります。ウェブページは、コピーしたテキストを書き換えたり、許可を与えられた時点で直接クリップボードに書き込んだりすることができます。いずれの場合も、ユーザーはまずそのページ上でクリックするか、キーを押す必要があります。
### 修正
JupyterLabの[`v4.6.4`](https://github.com/jupyterlab/jupyterlab/releases/tag/v4.6.4)および[`v4.5.11`](https://github.com/jupyterlab/jupyterlab/releases/tag/v4.5.11)には、この修正が含まれています。現在開いているウィンドウに紐付けられないシステムクリップボードから読み込まれたセルは、もはや`metadata.trusted`属性を持ちません。そのため、これらのセルの出力は、他の不明な起源のコンテンツと同様に安全化されます。
JupyterLabに依存するアプリケーション(Notebook v7+など)のユーザーは、`jupyterlab`パッケージもアップデートする必要があります。
### 対策
4.5.2以降のバージョンでは、システムクリップボードがセルで使用されていないことを確認してください。この設定はデフォルトでオフになっています。設定、ノートブック、または生の値を参照してください。
```json
{
"@jupyterlab/notebook-extension:tracker": {
"useSystemClipboardForCells": false
}
}
```
この設定をオフにすると、セルのコピー&ペーストはJupyterLabのアプリケーション内クリップボードを使用します。このクリップボードはページから外に出ることはありません。ただし、この設定では、セルのブラウザタブやウィンドウ間のコピーができなくなります。
4.5.0および4.5.1のバージョンには、この設定はありません。そのため、すべてのペースト操作でシステムクリップボードが読み込まれます。アップグレードを強く推奨します。
セルの出力を含まない状態でペーストすると、スクリプトの実行を停止できます。ただし、この方法では、ペーストするたびにセルの出力が破棄されます。
```json
{
"@jupyterlab/notebook-extension:tracker": {
"pasteCodeCellsWithoutOutput": true
}
}
```
影響を受けるパッケージ:
- pip (Python) jupyterlab: 影響を受けるバージョンは 4.6.0 以降、4.6.3 以下のバージョン。4.6.4 で修正済み。
- pip (Python) jupyterlab: 影響を受けるバージョンは 4.5.0 以降、4.5.10 以下のバージョン。4.5.11 で修正済み。
- pip (Python) notebook: 影響を受けるバージョンは 7.5.0 以降、7.6.2 以下のバージョン。7.6.3 で修正済み。
- pip (Python) jupyterlite: 影響を受けるバージョンは 0.7.0 以降、0.8.3 以下のバージョン。0.8.4 で修正済み。
- pip (Python) jupyterlite-core: 影響を受けるバージョンは 0.7.0 以降、0.8.3 以下のバージョン。0.8.4 で修正済み。