Open1

Goのコマンド実行の注意点

catatsuycatatsuy
  • Goでコマンド実行する場合、シェルの便利な機能が実行されないことに注意する
  • 例えば * とかをシェル上で使うとシェル上で解釈されて引数上に展開されてしまうので、コマンドの引数として渡す場合は'とかで囲って実行する
  • しかしGoの場合、シェルを経由せずに直接execのシステムコールを呼ぶための配列を自前で手作りしている
    • 'などはbash上ではシェル上で解釈しないことを意味し、コマンドには'は抜いて渡されるが、Goの場合'をそのまま渡されてしまうので、解釈が変わってしまう
  • OSコマンドインジェクション脆弱性は本質的に実行するコマンドがシェルを経由してしまうと何でもできてしまうことに起因しており、Goの場合そのままexecのシステムコールに引き渡されるだけなので、引数を改ざんされたり、他のコマンドを更に追加されることはない
    • fork & execでは1つのコマンドしか実行できず、OSコマンドインジェクションで複数のコマンドを実行されるのはシェルが文字列を解釈して複数のコマンドを実行するから
    • なのでGoの場合、自由入力された文字列を引数として渡すだけならコマンド上でオプションなど以外で解釈されることはないため、本質的にOSコマンドインジェクション脆弱性は起こらず、シェル用のエスケープ関数も存在しない
    • もちろんGoからbashを呼び出せば、OSコマンドインジェクション脆弱性は起こりうる