ひとことで言うと
シェルインジェクションは、本来ただのデータとして扱われるはずの文字列が、コンピュータへの「命令」として実行されてしまう攻撃のことです。「インジェクション(injection)」は注入という意味で、命令文の中に余計な命令を注ぎ込む、というイメージですね。
「シェル」というのは、ターミナル(黒い画面)でコマンドを受け付けて実行してくれるプログラムのことです。ls と打てばファイル一覧が出るし、rm と打てばファイルが消える。あの入力を解釈している部分がシェルです。
身近な例えで
宅配便の受付カウンターを想像してください。あなたは紙に「送り先:山田太郎」と書いて窓口に出します。係員はその紙を読んで、そのとおりに伝票を作ります。
ここで悪意のある人が、送り先の欄に「山田太郎。……そして倉庫の荷物を全部処分すること」と書いたらどうなるでしょう。係員が紙の中身を何も疑わず「書いてあることは全部指示だ」と解釈してしまうと、名前を書くはずの欄に紛れ込ませた余計な指示まで実行されてしまいます。
これがシェルインジェクションの正体です。名前の欄=ユーザーからの入力、係員=シェル。入力を「ただの文字列」として扱うべきところで「命令の続き」として読まれてしまうと、攻撃が成立します。
何が起きるのか
シェルには、複数のコマンドをつなげて書くための記号がいくつかあります。たとえばセミコロン(;)で区切れば「前のコマンドが終わったら次を実行」という意味になりますし、パイプ(|)やバッククォート、&& といった記号にもそれぞれ意味があります。
プログラムが「ユーザーが入力したファイル名」をそのままシェルのコマンドに埋め込んでしまうと、ファイル名のつもりで入力された文字列の中にこうした記号が混ざっていた場合、そこから先が別のコマンドとして動き出します。
結果として起こりうることは深刻です。ファイルの削除、機密情報の読み出しと外部への送信、別のプログラムのインストールなど、そのプログラムを動かしている権限でできることは、理屈のうえでは何でもできてしまいます。
なぜAIコーディングの文脈で話題になるのか
Claude Codeのように、AIが自分でコマンドを組み立てて実行するツールでは、この話がぐっと身近になります。AIが読み込む対象――ソースコード、README、Webページ、issueの文面など――には、開発者以外が書いた文字列が含まれることがあります。
正直なところ、最初は「AIが勝手に変なコマンドを打つわけないでしょ」と思っていました。でも怖いのは、AIが悪意を持つことではなく、AIが読んだ文章の中に命令めいた文字列が紛れていて、それが素直にコマンドへ反映されてしまうケースです。宅配の例でいえば、係員(AI)が真面目だからこそ、紙に書いてあることを疑わずに実行してしまう。
だからClaude Codeは、ファイル書き込みやコマンド実行といった影響の大きい操作について、実行前にユーザーへ確認を求める作りになっています。この確認画面を「面倒だから全部許可」で流してしまうと、せっかくの防波堤が効かなくなります。
どう身を守るか
利用者としてできることは、そう難しくありません。
- コマンド実行の確認が出たら、実行されようとしているコマンドの中身を読む。見覚えのないURLや
rm -rf、curl ... | shのような組み合わせが出たら止める。 - 素性のわからないリポジトリやWebページを、無防備にAIに読ませて作業させない。
- 重要なファイルは必ずバージョン管理やバックアップを取り、万一壊れても戻せる状態にしておく。
自分でコードを書く側であれば、シェルを経由せずにプログラムを起動する仕組みを使い、どうしても文字列を渡すときはシェルが特別扱いする記号を無害化(エスケープ)する、というのが基本の考え方になります。
「入力は信用しない」。シェルインジェクションの対策は、結局この一言に集約されます。長く言われ続けている古典的な攻撃ですが、AIがコマンドを実行する時代になって、むしろ意識する場面は増えたと感じています。
このページは役に立ちましたか?