PATHの「~」はHOMEではない罠

原題: The tilde in your PATH may not be your HOME

なぜ重要か

この設定ミスは長年の「常識」として普及しており、相対パス経由のコード実行という静かな攻撃面を多くの開発者環境に潜ませている。

シェル設定ファイルで`export PATH="$PATH:~/.local/bin/"`と書くと、`~`がホームディレクトリに展開されず、カレントディレクトリ配下の`./~/.local/bin/`がPATHに追加される。Bash/Zshのチルダ展開はクォート内では動作しないという仕様が原因で、悪意あるバイナリが実行される可能性がある。

セキュリティ研究者のDisconnect3d氏が2026年10月2日、自身のブログで指摘した。サンドボックスツール「nono」を使用中、「PATHに書き込み可能なエントリ: ~/.local/bin/」という警告が表示されたことが調査のきっかけとなった。

問題の核心はBashのチルダ展開の仕様にある。Bashドキュメントによれば、チルダ展開が行われるのは「クォートされていない入力」に限られる。`=`の後や`:`の後に続くチルダも、変数代入文がダブルクォートで囲まれている場合は展開されない。つまり`"$PATH:~/.local/bin/"`と書いた場合、`~`はそのまま文字列として扱われ、実際にPATHへ追加されるのは`./~/.local/bin/`という相対パスになる。

氏はデモとして、カレントディレクトリに`./~/.local/bin/`を作成し、そこにバイナリを置いた。`PATH="~/.local/bin/" kek`を実行すると、ホームディレクトリではなくカレントの`./~/.local/bin/kek`が実行された。攻撃者がこのディレクトリに書き込めれば、任意のコードを実行させられる。

クォートなしの`export PATH=$PATH:~/.local/bin`はBash・Zshともに正しく動作するが、空白文字が混入した場合に変数代入が破壊されるため脆弱だ。安全な書き方は`export PATH="$PATH:$HOME/.local/bin"`と`$HOME`を使うことだ。

自分のPATHを確認するには`echo "$PATH" | tr ':' '\n' | grep '~'`を実行すればよい。出力があれば`.bashrc`・`.zshrc`・`.profile`の修正が必要だ。

出典

disconnect3d.pl — 元記事を読む →