配布されているプラグインを入れる前に何を見るか — OrcaSlicer の許可制と PrusaSlicer のサンドボックスを AI と確かめる

配布されたプラグインを一本、スライサーに入れる。たったそれだけで、そのコードは手元のファイルを読み、ネットワークにつなぎ、別のプログラムを起こせる立場に立つ。OrcaSlicer 2.5.0-alpha(10-16)は Orca Cloud の plugin hub を公開し、PrusaSlicer は 3.0.0-alpha11(09-01)で署名つきのバンドルの仕組みを入れた(本稿が読むソースは後続の alpha12。マーケットプレイスはまだテスト中だ)。どちらも、プラグインを配る・受け取る前提が整いはじめている。問題は、入れる前にそのコードが何をするか読み切れないことだ。配布されているプラグインの安全を、入れる前にどう見極めるか。それがこの記事の主題である。
※本記事にはアフィリエイト広告(PR)が含まれます。
二つのスライサーは、まったく別のやり方でこの問題に答えている。OrcaSlicer は、プラグインに実行を許したうえで、OS に触れる操作のたびに利用者へ確認を求める「許可制」をとる。PrusaSlicer は、そもそも危ない操作ができる機能を Lua に渡さない「サンドボックス」をとる。本稿では、両方のリリースノートと、タグに固定したソースコードの原文から、入れる前に見るべき点を並べる。あわせて、手元にある正当なプラグイン10本を AI に読ませ、各プラグインが OS に触れる操作を正しく仕分けられるかを確かめた、この一回の実行の結果を添える。数値はすべて、固定コミットのソースと公式文書、そしてこの実行の記録にあるものだけを使う。
「許可制」と「サンドボックス」— プラグインの安全を支える二つの考え方

ここで言うプラグインとは、スライサーが読み込んで自分の中で動かす追加のコードを指す。OrcaSlicer は Python、PrusaSlicer は Lua で書く。名前は同じ「プラグイン」でも、試験ガイドに出てくる Claude Code の設定を手元で覚える — コーディングエージェントの MCP・スキル・フック・サブエージェントを1つずつ試す(2026-10-23 公開) で扱った Claude Code のプラグイン(スキルやフックをまとめたフォルダ)とは別物だ。こちらはスライサーという一つのアプリの中で動くコードである。
プラグインの安全を支える考え方は、二つに分かれる。OrcaSlicer は実行を止めない。その代わり、ファイルやネットワークといった OS の機能に手を伸ばした瞬間を捕まえ、プラグインの名前と「何をしようとしているか」を画面に出して利用者に聞く。公式のリリースノートは、これを明確に「サンドボックスではない」と書く。原文は “This is a permission system, not a sandbox, so only install plugins from sources you trust.” である。許可制とは、裏返せば「利用者が Yes を押した時点で、その操作は承認済み」という作りだ。
PrusaSlicer は逆の入り口から入る。危ない操作ができる道具を、最初から Lua に渡さない。Prusa の公式は Lua を選んだ理由を、原文で “This is why we chose Lua – the system is more or less designed to be sandboxed, and the plugin can be very simply restricted from accessing filesystem, executing other processes and similar.” と説明する。ファイルシステムへの到達や他プロセスの実行を、仕組みとして閉じておくという立場である。どちらが上という話ではない。守り方の層が違うだけだ。なお両版とも alpha で、公式は API が変わりうると明記している。正式版で挙動が変わりうることを前提に読んでほしい。二つのスライサーの位置づけの全体像は スライサーのプラグインが OrcaSlicer 2.5 と PrusaSlicer 3.0 に入った — 2つの試用版で何が変わり、何がまだ決まっていないか(2026-10-26 公開) で整理した。両者とも AGPL-3.0 のオープンソースである。
OrcaSlicer の許可制 — データフォルダの外を聞き、設定とトークンは止める

OrcaSlicer の許可制は、Python の監査フックの上に作られている。フックは Python 側の sys.addaudithook ではなく、C API の PySys_AddAuditHook で入れており、しかもインタープリタの初期化のあと、プラグインのコードが読み込まれるより前に入れている。入り口は、OS に触れる操作に対応するイベント名の対応表だ。固定コミットのソースでは、ファイルの読み書き・作成・削除、HTTP、ソケット、他プログラムの起動と置き換え、スレッドの作成に当たる 66 のイベント名が分類ごとに並び、これに加えて open だけはモード(読み取りか書き込みか)で扱いを決める特別扱いになっている。
許可を求める操作は、リリースノートの原文で “When a plugin tries to work with files outside OrcaSlicer’s data folder, connect to the network, launch another program (or replace OrcaSlicer with one) or start a background thread, a prompt names the plugin and what it wants, and your answer is remembered.” とまとめられている。データフォルダの外のファイル、ネットワーク、他プログラムの起動と置き換え、そしてバックグラウンドのスレッド。確認の画面はプラグイン名と内容を示し、答えは記憶される。ただし記憶されるのは一部だ。データフォルダの外にファイルやフォルダを作る操作と、消す操作は、記憶する一覧を持たないため毎回聞かれる。なお、プラグインは必要なファイルを先に申告でき、その場合は読み込みのときに一度だけ聞かれる。公式は “A plugin can list the files it needs up front, so you’re asked once when it loads.” と書く。
一方で、画面を出さずに最初から止める操作がある。設定ファイルと、Orca Cloud のログインのトークンだ。リリースノートは “Plugins can’t read OrcaSlicer’s own config file or your Orca Cloud login token” と書く。止め方は2通りある。設定ファイルとトークンは、登録された名前(OrcaSlicer の設定ファイルやトークンのファイル名)に対する前方一致で止める。大文字小文字は区別せず、その名前で始まるものを止めるので、同じ名前に .bak が付いた控えのようなものも止まる。これとは別に、パスの各要素が secret・secrets・cert・certs・certificate・certificates・conf・config のいずれかと完全に一致するフォルダ(要素の完全一致で、部分一致ではない。Conference のように一部に含むだけの名前は止まらない)と、.conf・.ini のファイルも止める。このフォルダ名の一覧はソースにこう書かれている。
return {"secret", "secrets", "cert", "certs", "certificate", "certificates", "conf", "config"};
ここで見落としやすいのが、この「止める」判定は、データフォルダを許す判定より先に行われることだ。だから、設定ファイル・トークン・secrets や config という名前のものは、データフォルダの中にあっても止まる。逆に言うと、それ以外のファイルなら、データフォルダの中は確認なしで読み書きできる。ソースのコメントは、データフォルダを原文で “the primary globally-allowed root during plugin execution: read+write” と書く。そしてこのフォルダの中には、プラグインの置き場所とプロファイルのキャッシュがある。開発者向けの文書と合わせて読むと、あるプラグインが別のプラグインのファイルを確認なしで書き換えられる作りだと読める。これはコードと文書を読んだうえでの推論で、動かして確かめてはいない。同梱の Python は、ビルドの設定の値では 3.12.13 である。OrcaSlicer 自身が公式に「サンドボックスではない」と言うとおり、一度 Yes を押したあとにプラグインを隔てる層はない。
監査されない箇所 — 読み込み時・スレッドの中・ネイティブコード

入れる前に特に効くのは、許可制が見ていない箇所を知っておくことだ。確認の画面は、プラグインの関数が C++ 側から呼ばれる「中継部分」を通ったときの操作にだけ出る。裏返せば、その経路の外で動くコードは、OS に触れても聞かれない。該当するのは三つある。
一つ目は、読み込みのときに動くコードだ。公式の開発者向け文書は原文で “and plugin import/registration before the first trampoline call, stay unaudited.” と書く。最初の中継呼び出しより前、つまりプラグインの読み込みと登録の段階は監査の文脈の外にある。ソースでも監査の文脈は「いま動いているプラグイン」を表すスレッドごとの変数で持っており、読み込みの経路にはその文脈を開くマクロが入っていない。したがって、モジュールの最上位に書いたコードは、ファイルを読もうとネットワークにつなごうと聞かれない。これはコードと文書の読みによるもので、動かして確かめてはいない。
二つ目は、プラグインが自分で立てたスレッドの中だ。文書は原文で “the context does not propagate to a Python thread the plugin spawns itself” と書く。監査の文脈はスレッドごとの変数なので、新しいスレッドには引き継がれない。つまりスレッドを立てる時点は聞かれる(スレッドの作成は Threading の分類にある)が、そのスレッドの中で起きる操作は通ってしまう。三つ目は、ネイティブコードの読み込みだ。OrcaSlicer の対応表に ctypes のイベントは無い。Python の監査イベント表には “ctypes.dlopen name” があるが、OrcaSlicer の表はこれを拾っていない。開発者向け文書も native-code loading は対象外だと書く。ここで言えるのは「対応表に ctypes のイベントが無い」までで、同梱の Python に ctypes が入っているかは確かめていない。
G-code の後処理の段階にも、確認の対象から外れる範囲がある。ソースのコメントは、この段(Step.psGCodePostProcess)について原文で “At this step the plugin edits the exported G-code file in place” と書く。公式 wiki によると、書き出した G-code のあるフォルダは、この段の呼び出しの間だけ確認なしで読み書きできる。G-code の中身を書き換えても、それは OS の操作ではないので許可の仕組みは見ない。監査が見るのは OS の操作のイベントだけだからだ。書き換えた G-code の命令が造形に及ぼす影響は、この記事の範囲を超える。
もう一つ、文字列として受け取ったコードを実行する操作(Python の exec や compile)も、OrcaSlicer の対応表には無い。中身を文字列に包んで動かすコードは、その実行そのものについては聞かれない。もっとも、実行された中身が OS に触れれば、監査の文脈の中にいる限り個別に捕まる。だから「見えない箇所」は、文脈の外(読み込み時・立てたスレッドの中)と、監査がそもそも見ないもの(OS に触れない操作、ネイティブコード)の二層に分かれる。
ここで Python の文書そのものにも触れておく価値がある。Python の文書も PEP 578 も、監査フックは「内部の、ふだん見えない動作についての情報を集めるもの」で、サンドボックスには向かないと書く。注意したいのは、文書が “In particular, malicious code can trivially disable or bypass hooks added using this function.” と書くとき、この “this function” は Python 側の関数 sys.addaudithook を指すことだ。OrcaSlicer はフックを C API で入れている。だから、この一文をそのまま OrcaSlicer に当てはめることはできない。言えるのは「監査フックという仕組みそのものは、サンドボックスの代わりではない」というところまでで、これは OrcaSlicer が自ら「サンドボックスではない」と言うことと同じ向きを向いている。
PrusaSlicer のサンドボックス — Lua に開いているライブラリと、消した関数

PrusaSlicer は、Lua 5.4.8 を sol2 というライブラリ経由で読み込み、開く標準ライブラリを選んでいる。開いているのは base・table・math・string の四つだけだ。ソースはこう書く。
m_state.open_libraries(sol::lib::base, sol::lib::table, sol::lib::math, sol::lib::string);
ここに io・os・package・debug は無い。coroutine も utf8 も開いていない。さらに base に残る dofile・loadfile・load は、わざわざ消している。
ban_keys(m_state, {"dofile", "loadfile", "load"});
モジュールの読み込みに使う require も、PrusaSlicer が用意したものに置き換えられている。読めるのは拡張子 .lua のファイルで、しかもプラグインのフォルダの中からだけだ。フォルダの外を指すパス(先頭が .. のものや空のもの)は拒まれる。Lua からファイルを読む API も同じ仕組みの上にあり、STL と SVG を読む関数も、プラグインのフォルダの中に限られる。だから PrusaSlicer のプラグインは「ファイルに一切触れない」のではなく、「自分のフォルダの中の .lua・STL・SVG だけを読める」と言うのが正確だ。
この点は OrcaSlicer と対照的でもある。load・loadfile・dofile を消しているため、PrusaSlicer のプラグインは文字列をそのままコードとして動かす手段を持たない。中身を文字列に隠して実行するという逃げ道が、入り口の時点でふさがれている。OrcaSlicer では同じ操作が聞かれずに通るのに対し、PrusaSlicer はそもそもその操作を渡していない、という守りの層の違いがここにも出る。
では、ネットワークはどうか。Prusa の公式の文に「ネットワーク不可」という言葉は無い。言えるのは二つの事実からだ。まず Lua の標準ライブラリに、そもそも通信の機能が無い。lua.org のマニュアルが並べる標準ライブラリ(basic・coroutine・package・string・utf8・table・math・io・os・debug)に、ネットワークのライブラリは含まれない。そのうえ PrusaSlicer は io・os・package・debug を開いてもいない。開いていないライブラリが何を閉じているかを並べると、守りの形がはっきりする。os.execute はシェルでコマンドを走らせ、io.popen は別のプログラムを起こし、os.remove はファイルを消し、package.loadlib は C のライブラリをつなぐ。この package.loadlib が、OrcaSlicer で監査されないネイティブコードの読み込みと、ちょうど対になっている。PrusaSlicer はこれらの入り口を最初から渡していない。
プラグインの種類も一つに絞られている。ソースでは project.plugin の一種だけで、公式も用途を原文で “The purpose of currently existing plugins is to create objects programmatically.” と書く。オブジェクトを作ることが目的で、OrcaSlicer のような G-code の後処理の種類は無い。そして OrcaSlicer との大きな違いとして、PrusaSlicer は起動時の走査でバンドルの中の .lua を一度実行して情報を読むが、その実行も同じ制限つきの Lua の中で起きる。読み込みのときのコードまで制限の内側に置かれている点が、OrcaSlicer と対照的だ。これも alpha の版で、公式は Lua API を実験的で変わりうると書く。
署名つきの配布 — PrusaSlicer が zip を確かめ、OrcaSlicer は入れ直しで許可を消す

配布の場で入れる以上、「そのプラグインが本当にその作者のものか」も、入れる前の確認に入る。PrusaSlicer は、この署名の道具を CLI に持っている。サブコマンドは plugin の init・keygen・sign の三つだ。keygen は RSA の鍵の組を作る。既定は 2048 ビットで、1024 から 8192 の 2 のべき乗が選べる。sign は、バンドルの中の各ファイルの SHA-256 を manifest.txt に書き出し、その一覧を秘密鍵で署名して manifest.sign に書く。zip から入れるときには、作者の公開鍵で署名と各ファイルを照合し、合わなければ入れない。合わないときのメッセージは原文で “Plugin installation failed: Integrity verification failed for bundle” である。
ただし、ここで書けるのは「zip から入れるときに署名を確かめる」までだ。公式はマーケットプレイスを原文で “The marketplace is currently in testing and it will be launched in the near future.” と書いており、状態はテスト中である。公開済みとは書かない。起動時の走査がどのフォルダを対象にするか、利用者が作者の鍵を自分で登録できるかは、このソースの範囲では確かめられていない。だから「フォルダに置けば署名なしで動く」といった踏み込んだ書き方はしない。
OrcaSlicer 側は、署名とは別の守りを持つ。プラグインを入れ直すか更新するたびに、そのプラグインの許可をすべて取り消す作りだ。ソースの関数名は revoke_plugin_permissions で、文書も新しいコードは改めて許可を取り直す必要があると書く。クラウドからの取得については、リリースノートが “Cloud plugin downloads check the server’s certificate.” と書く。これは通信路が正しい相手につながっているかの確認であって、取得した中身を審査するという意味ではない。Orca Cloud については「誰でも公開できる」という説明はあるが、公開前の審査やモデレーション、通報の手順についての公式の説明は、2026-10-20 時点では見つからなかった。見つからないことを「審査が無い」とは書けない。同じ理由で、OrcaSlicer のプラグインに署名の仕組みが無いとも書かない。このソースでは確かめていないからだ。
正当なプラグイン10本を AI に審査させた — この実行で分かったこと

ここまでの分類は、ソースとリリースノートを読んで作ったものだ。では、入れる前の読み取りを AI に手伝わせるとどうなるか。OrcaSlicer のプラグインの仕組みは画面側のコードにあり、当サイトはスライサーの画面を操作していない。そこで、手元にある正当なプラグイン10本のソースを claude -p に読ませ、各プラグインが OS に触れる操作を許可の分類(聞く/止める/通る)に当てはめさせ、監査されない箇所を見抜けるか、正当なプラグインに過剰な警告を出さないかを見た。危ない動きを仕込んだ試験用のプラグインは使っていない。送信先が存在しないドメイン(RFC 2606 で無効が保証された .invalid)のコードも書いていない。あくまで正当なプラグインで試した。
題材は、公式サンプル7本と、別の検証で作った入れても安全な良品3本である。条件は二つにした。許可の仕組みを AI が思い出して判断する「資料なし」と、公式の開発者向け文書を渡す「資料あり」だ。10本に2条件で、合わせて 20 回。この回の費用は合計でおよそ 1.5 ドルだった。各条件は1回ずつなので、以下は「この実行ではこうだった」という記録である。
| 条件 | 入れてよいと正答 | 誤った「止める」 | 監査されない箇所に言及 |
|---|---|---|---|
| 資料なし | 10/10 | 0 | 9/10 |
| 資料あり | 10/10 | 0 | 10/10 |
結果は三点にまとまる。第一に、AI は10本すべてを「入れてよい」と正しく判定した。両条件ともだ。第二に、正当な操作を「止められる」と誤って警告することは一度も無かった。過剰な警告がゼロだったのは、プラグインの安全を見極める道具として大事な性質である。危なくないものを危ないと言い続ける検査は、使ううちに無視されるからだ。第三に、監査されない箇所をほぼ毎回指摘した。読み込み時のコード、自分で立てたスレッドの中、ネイティブコードの読み込みの三つを、条件を問わず挙げてきた。ある一本では「numpy が読み込み時に自前のネイティブ拡張を監査の外で読む」とまで指摘した。ただし、この三つは審査の指示文そのものに「読み込み時・自分で立てたスレッドの中・ctypes 経由など、監査されずに動く箇所があれば指摘してください」と挙げてある。だから今回確かめたのは、AI がこれらの観点をゼロから発見したことではなく、挙げた観点を、渡したソースに正しく当てはめて具体化できたことだ。numpy のネイティブ拡張のように、観点を具体的なコードに結びつけた指摘は、その当てはめが働いた例といえる。
ただし、具体的な取り違えが一つあった。二本のプラグインで、スレッドを立てる操作そのものを「監査されない(通る)」と判定したのだ。ソースではスレッドの作成は Threading の分類にあり、確認の画面が出る。AI は、スレッドの「中」が監査の外になること(これは正しい)と、スレッドを「立てる」時点の扱いを取り違えた。概念としての抜け穴は正しく捉えるのに、個別の判定規則を一つ外した形である。なお、操作の分類の一致が 8 項目中 5 だったのは、採点側の仕組みが粗く、AI が「メモリ上のプリセットを読む」と正しく書いたものを文字列の一致でファイル操作に数えてしまった取り過ぎを含む。AI の記述自体は正確だった。
この一回から言えるのは、プラグインの安全を AI に手伝わせるとき、抜け穴の説明は頼れるが、個別の判定規則は公式の資料で裏を取るべきだということだ。画面の中で動かしたわけではなく、版は alpha で、各条件は1回ずつである。ここは一般化できる広さではない。
AI にコードを読ませて危ない箇所を探させるときの考え方は、生成AIのセキュリティ全般とつながっている。
入れる前に確かめること

配布されているプラグインの安全は、入れた後に働く機能ではなく、入れる前に何を見るかで決まる。二つのスライサーの作りを、入れる前の確認に落とし込むとこうなる。
- 出どころを見る。両方の公式が、信頼できる出どころからだけ入れよと書く。許可制もサンドボックスも、悪意を持って回り道をするコードまでは止めきれない
- 版を見る。どちらも alpha で、API が変わると公式が明記している。正式版で挙動が変わりうる前提で読む
- OrcaSlicer を入れるなら、データフォルダの外は聞かれるが中は聞かれないこと、入れ直しで許可が消えること、読み込み時・スレッドの中・ネイティブコードが監査の外にあること、設定ファイルとトークンは名前の前方一致で、
secrets・configなどのフォルダは名前の完全一致で(データフォルダの中でも)止まることを押さえる - PrusaSlicer を入れるなら、Lua に危ない機能を渡さないサンドボックスであること、読めるのは自分のフォルダの
.lua・STL・SVG だけであること、zip から入れるときに署名を確かめること(マーケットプレイスはテスト中)を押さえる - AI に読ませるなら、抜け穴の説明に使い、個別の規則は公式の資料で裏を取る
配布の場そのものにも、同じ構えが要る。スライサーのプラグインとは別の話だが、Bambu Lab のモデル共有サイト MakerWorld では、2026-09-01 に公式アカウントがフォーラムで、問題を指摘されたリミックスを取り下げたと答えた一件がある。これはスライサーのプラグインではなく、モデルのページで起きたことだ。入れる・開く前に出どころを見るという一点は、プラグインでもモデルでも変わらない。プラグインの安全は、結局のところ、Yes を押す前の数秒に何を確かめたかに尽きる。
許可を与えるか、最初から渡さないか。AI エージェントに外部のツールを使わせるときも、同じ問いに向き合うことになる。
参照
- OrcaSlicer v2.5.0-alpha リリースノート
- OrcaSlicer src/slic3r/plugin/PluginAuditManager.cpp(固定コミット 3880f2c)
- OrcaSlicer 公式 wiki「Plugin Audit Hook」
- PrusaSlicer 3.0.0-alpha11 リリースノート
- PrusaSlicer LuaEngine.cpp(固定コミット 30ef591)
- PrusaSlicer PluginCliOps.cpp(固定コミット 30ef591)
- Python 3.12 文書 sys(監査フック)
- PEP 578 – Python Runtime Audit Hooks
- Lua 5.4 Reference Manual
- Bambu Lab フォーラムのスレッド(MakerWorld 公式アカウントの返信を含む)





