なぜ対策が必要か

QGIS Live Driver が提供する pyeval は QGISプロセス内での任意Python実行です。 iface・QgsProject・OS APIにフルアクセスでき、実質的にQGISユーザ権限での 任意コード実行に相当します。対策なしに有効化すると「認証なしのローカルRCEサーバ」が 常駐する形になるため、Driverは既定で無害・有効化はopt-in・全チャネル認証必須 という設計になっています。

防御の全体像

flowchart TB
    subgraph ATK["遮断される相手"]
        direction TB
        A1["外部ネットワーク"]
        A2["同一マシンの他OSユーザ"]
        A3["ブラウザ内の悪意ページ"]
    end
    A1 & A2 & A3 -.->|遮断| D1
    D1["1. 既定OFF(opt-in有効化)"]
    D2["2. 127.0.0.1 バインドのみ"]
    D3["3. 全チャネルでセッショントークン必須<br/>(トークンはユーザ限定ACLファイルに保存)"]
    D4["4. Host/Origin がloopback以外なら拒否"]
    SVC["QGIS Live Driver<br/>pyeval / screenshot / bridge_call ..."]
    D1 --> D2 --> D3 --> D4 --> SVC

攻撃者モデル:誰を防ぎ、誰を防がないか

相手到達性結果防御手段
外部ネットワーク 不可 接続自体が拒否 127.0.0.1 へのみバインド。トンネル公開は設計対象外
同一マシンの他OSユーザ ポートには届く トークンを読めず全要求が拒否 トークンファイル・レジストリにユーザ限定ACL(Windows: icacls / POSIX: chmod 600)
ブラウザ内の悪意ページ(ドライブバイ) no-cors POSTは届く トークン不在で401/破棄 全エンドポイントでトークン照合 + Host/Origin がloopback以外なら403
同一ユーザ権限の任意プロセス 届く 防げない(トークンを読める) なし — これが脅威モデルの境界(下記)

各防御層の詳細

1. 既定無害(有効化はopt-in)

インストール直後は何もしません。起動するのは次のどちらかの場合だけです:

OFFの間はHTTPポートもlive dirも作られないため、攻撃面は存在しません。

2. localhost限定

内蔵HTTPサーバは 127.0.0.1 にのみバインドします。LAN/外部からは到達不能です。 ngrok等のトンネル経由でも Host ヘッダがloopback以外になるため403で拒否されます (外部公開は設計対象外)。

3. セッショントークン(全チャネル必須)

4. Host/Origin検証(ブラウザ経由対策)

ブラウザからは fetch(url, {mode:'no-cors'}) でlocalhostへPOSTできます(DNSリバインドや 悪意ページのドライブバイ攻撃)。これに対し Host/Origin が 127.0.0.1/localhost 以外を指す要求は403で拒否します。 トークン必須と合わせた二重の防御です。

5. トークンの保存とACL

トークンは <live_dir>/token とレジストリJSON (~/.qgis-live/<pid>-qgis_live_driver.json)にのみ保存され、 作成直後にユーザ限定ACLを適用します(Windows: icacls /inheritance:r + /grant:r、 POSIX: chmod 600)。正規クライアント(Harness・mcp_stdio.py・自作ツール)は ここから自動読み取りするため、利用者がトークンを意識する必要はありません。

脅威モデルの境界(防げないもの)

同一ユーザ権限で動く任意プロセスは防げません。 トークンファイルを読めるため、あなたのアカウントで動くマルウェアには防御不能です。 これはOSの責任範囲であり、あらゆるlocalhostサービスに共通する限界です。 信頼境界はローカルユーザアカウントです。

その他の残存リスク:

運用上の推奨

脆弱性の報告

セキュリティ上の問題を見つけた場合は、公開Issueではなく GitHubリポジトリ の メンテナへ個別に連絡してください(リポジトリの SECURITY.md も参照)。