目次を開く
CSVはただのテキストファイルですが、表計算ソフトで開いた瞬間に値が「数式」として解釈されることがあります。
これがCSVインジェクション、またはFormula Injectionと呼ばれる問題です。
顧客名、問い合わせ内容、備考など、外部から入力された文字列をCSVへそのまま書き出す仕組みでは特に注意が必要です。
CSVインジェクションとは
CSVそのものがプログラムを実行するわけではありません。
問題になるのは、CSVをExcelなどの表計算ソフトで開いたときです。
セルの値が = など特定の文字で始まると、単なる文字列ではなく数式として扱われる場合があります。
たとえば、利用者が入力した値を管理画面からCSV出力できるサービスを考えます。
その入力値が数式として解釈される形のままCSVへ入り、担当者が表計算ソフトで開けば、意図しない処理につながる可能性があります。
どんな値を確認するべきか
OWASPはCSV Injectionの注意点として、セル先頭の次のような文字を挙げています。
=+-@- タブや改行などの制御文字
ただし「先頭だけ見れば絶対安全」と考えるのも危険です。
区切り文字や引用符の処理によって、元データとは違う位置から新しいセルとして解釈される可能性もあるためです。
「Excelで警告が出るから大丈夫」ではない
表計算ソフト側の警告や保護機能は重要です。
それでも、CSVを生成する側が安全性を全部アプリ任せにするのは避けた方がいい。
利用者の入力を含むCSVを外部へ渡すなら、出力前に値の性質を確認し、受け取り側の仕様まで含めて扱いを決めます。
対策は「全部エスケープ」ではなく用途から決める
よくある対策として、危険になり得る値の先頭にアポストロフィを付け、文字列として扱わせる方法があります。
ただし、これは万能ではありません。
受け取り先によってはアポストロフィ自体がデータとして残ります。別システムへ再インポートするCSVなら、元データを変えてしまうことにもなります。
安全な順番は次です。
- どの列に外部入力が入るか把握する
- その列で許容する値を決める
- CSV生成時に危険な値を検査する
- 出力先・閲覧先に合った方法で文字列として保持する
- 実際に使う表計算ソフトやインポート先でテストする
メールアドレス、商品コード、電話番号など、形式を限定できる列は許容ルールを明確にしやすい。
一方、備考や問い合わせ内容のような自由入力欄は、より慎重な扱いが必要です。
CSVを受け取った側でできる確認
自分がCSVの生成者ではなく、取引先や顧客からファイルを受け取る側なら、次を確認します。
- 出所が分からないCSVをいきなり表計算ソフトで開かない
- テキストとして内容を確認する
- 数式として解釈されそうなセルがないかを見る
- 列数や引用符の崩れも同時に確認する
- 本番システムへ入れる前に少量で試す
CSVの一般的なインポート事故については、CSVインポートエラーの確認手順も参照できます。
まとめ
CSVインジェクションは「CSVファイルが危険」という話ではありません。
文字列として渡したつもりの値を、受け取り側が数式として解釈する境界が問題です。
外部入力をCSVへ出力する場合は、値の検査と出力先の仕様確認をセットにする。受け取る側も、出所の分からないCSVを無条件で開かない。
構造上の崩れを含めてインポート前に確認したい場合は、CSV Preflightでファイルを先に検査できます。
