ガードとシェルの見解は食い違っていた
6月30日、Adversa AIはGuardFallを公表した——数十年前のbashの小技を、人気のオープンソース・コーディングエージェント11本のうち10本に組み込まれたコマンドガードの前を素通りさせる、一群のバイパスだ。理由は単純で、その層では修正不能だ。ガードはテキストを読み、bashは実行前にテキストを書き換える。Bromure Agentic Codingは、ガードがbashを正しく読むことに賭けたことは一度もない。コマンドは、実行される時点では意味を持たない——それに賭けた。
あるコーディングエージェントの安全フィルターは、文字列r''m -rf ~を見て、
認識できないコマンドだと判断し、通してしまった。bashは同じ文字列を見て、
空の引用符を捨て、rm -rf ~を実行した。フィルターとシェルは、二つの
異なる言語を読んでいた。この隔たりは一つのツールのバグではない——エージェントが
打つコマンドをパターン照合で守るという発想そのものであり、Adversa AIは
それが、試した十一本中十本のエージェントで破綻することを、いま示した。
コマンドガードは、あらゆるエージェント型コーディングツールが真っ先に手を伸ばす
機能だ。エージェントがシェルコマンドを提案する。フィルターが文字列を検査する。
それが破壊的に見えれば——rm -rf、パイプでつないだcurl … | sh、生デバイスへの
dd——ガードはそれを遮断するか、確認を求める。自動実行をオンにして安全だと
感じさせてくれる当のものだ。2026年6月30日、Adversa
AI
が研究を公表し、The Hacker
News
とSecurityWeek
が取り上げ、その機能が芝居に過ぎないことを示した。
GuardFallとは何か
彼らはそれをGuardFallと呼び、CVEではない。修正すべきものは何もない。なぜなら 一つの部品の欠陥ではなく——二つの部品の不整合だからだ。Adversaの言葉では、 「ガードは生のテキストを検査し、一方でシステムシェル(bash)は実行前にテキストを 展開し、引用符を外し、書き換える」。フィルターはモデルが吐いた文字列に照合する。 bashはその後、単一のバイトが実行される前に、その文字列を引用符の除去、変数展開、 コマンド置換に通す。両者は決して同じコマンドを見ないので、書き換えは生き延びるが 照合には引っかからない小技は、どれも素通りする。
これらの小技は、エージェントを使う人々の大半より古い。Adversaはそれらを五つの クラスにまとめた。
- 引用符の除去。
r''mは正規表現には二つのトークンだが、bashには単語rmで、 空の引用符を捨てる。 - 変数展開。
rm$IFS-rf$IFS/はパターン照合器には長い一語に見えるが、bashは 内部フィールド区切り文字を展開してrm -rf /を得る。 - コマンド置換。
$(echo rm) -rf /は危険な動詞を$( )の中に隠す。外側の 文字列を検査するガードはrmを決して見ない。 - 符号化パイプライン。
echo <base64> | base64 -d | sh——見えるトークンは どれも無害で、ペイロードは復号後にしか存在しない。 - 別の破壊的フラグ。
rmは一切なし。find /x -delete、tar -C / -x、sed -i。rmとddを軸に組んだ拒否リストは決して発火しない。
Adversaはこれらを、最も使われているオープンソースのコーディング・コンピュータ
利用エージェント十一本に対して走らせた——opencode、Goose、Cline、Roo-Code、
Aider、Plandex、Open Interpreter、OpenHands、SWE-agent、そしてHermesプロジェクトが
その中にあり、五月時点で合計およそ548,000のGitHubスター
を集めている。十本が倒れた。持ちこたえた唯一のもの、Continueが持ちこたえたのは
明確な理由による。生の文字列に照合するのではなく、決定する前にbashがやるとおりに
コマンドをトークン化する——引用符を吸収し、$IFSを解決し、置換から内側のコマンドを
取り出し、shで終わるパイプに印を付ける。シェルをモデル化するのだ。それがガードの
層で機能する唯一のことであり、残る十本がいまや、正しく再現し、bashのあらゆる境界
ケースとあらゆるリリースにわたって正しく保たねばならない、本物で丁寧な工学だ。
問題は正規表現ではなく、その層だ
誘惑は、GuardFallを「十のチームが弱いフィルターを書いた」と読むことだ。それは Adversaの言っていることを取り逃がす。彼らの最も鋭い一文は、どの単一のエージェントに ついてでもない。
オペレーターのホスト上で任意のシェルコマンドを実行でき、LLMが吐いた文字列に 照合する正規表現で守られているエージェントは、防御ではない。それは、完全に 有効化され正しく設定された状態で破綻する。なぜなら文字列照合は、bashが何を 実行するかをモデル化できないからだ。
完全に有効化され正しく設定された。 これは、あなたが閉じられる設定ミスではない。 ガードは、決して勝てない唯一の層に座っている——文字列を書くモデルと、それを再解釈 するシェルの間に——そして、チューリング完全な展開器の出力を予測せよ、とテキスト 照合器に求めている。Continueのトークン化・正規化のやり方は、ガードにbashのように 考えることを教えて隔たりを狭める。ガードをそこに置き続けるなら、それは正しい 一手だ。だがそれは、コマンドを書き換える術を三十年かけて積み上げてきたシェルを 解析で上回るという、エージェント単位・リリース単位の約束事だ。他の九本の人気 エージェントが、それを誤るのがいかに容易かを示している。
Adversaの代償的統制は物語る。あらゆる構造的な修正に先立って、彼らはこう告げる。
プロジェクトへのアクセスは保ちつつ認証情報を取り除く、限定されたサンドボックスへ
$HOMEを振り向けよと。自動実行フラグを剥がせと。信頼できないプルリクエスト上で
エージェントを走らせるなと。リポジトリの設定ファイルはすべて信頼できないコードとして
扱えと。そのリストをもう一度読んでほしい。より良いフィルターの書き方についての助言では
ない。エージェントの周りに箱を築く助言だ——フィルターが負けたとき、そして彼らは
負けると告げている、素通りしたコマンドが、あなたを傷つけられない場所に着地するように。
その箱こそが製品だ。
Bromureはガードにbashを読ませたことがない
Bromure Agentic Codingは、GuardFallが証明する前提から出発する。エージェントは
遅かれ早かれ、あなたが認可していないコマンドを実行する。それを読んで捕まえようとは
しない。エージェントまるごと——Aider、Goose、opencode、十本のどれでも好きなものを
——使い捨てのLinux VMの中で走らせ、あらゆるネットワーク要求をホスト上のプロキシ経由で
送り出す。設計上の問いは決して「フィルターはこのrmを認識するか?」ではない。
「そのrmが走るとき、何に届くのか?」だ。
GuardFall自身のペイロードを、その箱に通してみよう。
攻撃の要点は、隠されたr''mやfind /x -deleteが仕掛け入りのREADMEをガードの
前に滑り込ませたあと、そのアカウントが届くもの——Adversaは~/.ssh、~/.aws、
クラウド認証情報、「ホームフォルダーにあるもの何でも」を挙げる——を盗み、消すか
持ち出すことにある。Bromureでは、それらは初めから箱になかったものだ。本物の秘密は
決してVMに入らない。プロファイルにAWS_SECRET_ACCESS_KEY、GitHubトークン、
Anthropicキーを与えると、エージェントの環境にはbrm_…のプレースホルダーが入り、
ホストのプロキシが、それを受け取るべきプロバイダー宛の送信要求のときだけ、通信路上で
偽物を本物の値に差し替える。Adversaの推奨する緩和策——「プロジェクトへのアクセスは
保ちつつ認証情報を取り除く」どこかへ$HOMEを移す——は、Bromureのプロファイルが
既定で、すべての認証情報について、あなたがスクリプトを書くことなく行うことの、
手作りで部分的な版だ。
破壊的な半分も同じように着地する。ガードをすり抜けたfind /x -deleteやsed -iは
実際に走る——Bromureはコマンドを捕まえたふりをしない。それは、共有のベースから
クローンされたホームディレクトリに対して、インシデント用のフォームではなくメニューから
消して基底へリセットできるVM上で走る。ペイロードが仕込むかもしれない永続性は、その
リセットで死ぬ。そして、あらゆる要求がホストのプロキシを通って出ていくので、GuardFallの
符号化パイプラインのクラスが隠すために作られたcurl … | base64 -dのビーコンは、
不可視ではない——それはセキュリティログの、記録され帰属可能な一行だ。
通信路がシェルに勝つ唯一の場所
Bromureは破壊的操作のガードを確かに保っている——ホスト側のGuardrailsであり、 Cursorのエージェントが本番データベースを九秒で削除した 後に我々が書いたものだ。そしてここでは層がBromureに有利に働く。なぜならGuardrailsは GuardFallの棲む場所には棲んでいないからだ。
GuardFallはシェルテキストの攻撃だ。その五つのクラスのどれもが——引用符の除去、
$IFS、$( )、base64パイプライン、風変わりなフラグ——bashが文字列をどう字句解析
するかの小技だ。BromureのGuardrailsはその文字列を決して読まない。ホストのプロキシに
座り、エージェントが理解しているプロバイダーへ行う構造化されたAPI呼び出しを分類する
——AWS、Kubernetes、gitフォージ、マネージドデータベースへの実際のHTTPS要求だ——そして
破壊的なものには通信路上で固い403を返す。VM内の侵害されたエージェントがそれを
切ることのできない場所で。要求がその層に達する頃には、それはもう解析済みの
DeleteDBInstanceであって、引用符とドル記号の文字列ではない。何かを密輸するシェルの
書き換えは存在しない。経路にシェルがないからだ。GuardFallの技法全体は、検査と行動の
間にbashを必要とする。Guardrailsの経路には、それがない。
これが何に線を引くのか、はっきりさせるために
コマンドはやはり走る
Bromureは隔離であって、傍受ではない。あなたのエージェント自身のガードをすり抜けた GuardFallのペイロードは、VM内で実行される。Bromureが変えるのは被害範囲だ—— 使い捨てのホーム、囮の認証情報、記録された送出経路。コマンド自体を拒否させたいなら、 それはあなたのエージェントのガードの仕事だ——そしてGuardFallは、それに頼るべきでない 理由だ。
ローカルの破壊は使い捨て性であって、遮断ではない
VM内のファイルに対するfind /x -deleteはプロバイダーのAPI呼び出しではないので、
Guardrailsはそれをゲートしない。VM内の破壊への答えは、VMが使い捨てで、本当の仕事は
マウントされたリポジトリとホスト上にあるということであって、削除が止められたという
ことではない。ロールバックではなく、基底へのリセットだ。
差し替えは、あなたが設定した認証情報を守る
brm_…の差し替えは、あなたがプロファイルに入れた秘密を守る——モデルキー、クラウドと
gitのトークン、マネージドデータベースのエンドポイント。あなたが箱の中のファイルに
手で貼り付けたパスワードや、セッション中にスクリプトがディスクに書くトークンは、
ただのファイルだ。秘密はワークスペースではなく、ブローカーに置くこと。
送出は記録され、既定で禁止はされない
持ち出しのビーコンはセキュリティログに現れる。それは帰属であって、防止ではない。 認証情報が囮なので本物は何も出ていかないが、任意のホストとの通信をVMに禁じる必要が あるなら、それはあなたがなお設定するネットワークポリシーだ。
一般化する部分
GuardFallは、この分野全体が繰り返し学び直している一つの規則の、明快な言明だ。 フィルターにコマンドが何をするかを予測させることで、エージェントを安全にはできない。 モデルは文字列を書き、そのどこか下でシェル、APIクライアント、パッケージマネージャー、 あるいはブラウザが、その文字列を自分の規則で再解釈する。エージェントの出力を検査し、 それが最終的な挙動に一致することを願うすべての防御は、その隔たりに逆張りしており、 隔たりは常に勝つ——ここでも、Adversaの言葉で言えば完全に有効化され正しく設定された 十一本中十本のエージェントで勝った。
Bromure Agentic Codingはその賭けをしない。コマンドは走る、ガードは時に見落とす、 そして招き入れたエージェントは、あなたが書いてもいないREADMEによってあなたに牙を 剥きうる、と想定する。だから、コマンドが走る場所を攻撃する価値のないものにする—— ホスト上の本物の鍵、箱の中の囮、使い捨てのVM、どのシェルも書き換えられない通信路の ために取っておいた固い遮断、そして出ようとしたすべての記録だ。GuardFallが破った十本の エージェントのどれを走らせてもよい——結果はどのみち同じ使い捨ての箱だ。それは自由で オープンソースだ。