SQLインジェクションと危険なアップロードを入力境界で止める
しろまえ殿は、入力値を信用してから後で整える設計をやめた。 SQLへ渡す場所とファイルを保存する場所で、受け入れる値を明示的に絞った。
SQLの組み立て方を揃える
SQLインジェクションは、入力値がSQLの命令として解釈される問題だ。 対策の基本は、SQL本体と値を分離するプレースホルダーである。
SQL文には値を直接埋め込まない。 値はバインド配列へ順番に追加し、データベースへ別途渡す。 プレースホルダーの書式もコードベースで統一する。
たとえば、手紙の本文と宛先を同じ欄へ書かないようにする。 本文へ宛先の指示が混ざっても、配送側は宛先欄だけを見る。 SQLも同じで、命令と値の境界を保つ。
JSON化や文字列置換だけで安全だと判断してはいけない。 文字列の見た目を変えても、SQLの構文へ混ざる経路が残ることがある。 検索条件、配列条件、JSON演算子へ渡す値も、同じバインド方針で扱う。
拡張子は許可リストで決める
ファイルアップロードでは、利用者が送った拡張子をそのまま保存名へ使わない。 許可する拡張子を明示し、それ以外を拒否する。
許可リストは、禁止語を増やし続ける方式より保守しやすい。 必要な形式がJPEG、PNGだけなら、その二つだけを許可する。 大文字小文字、空白、区切り文字の扱いも先に決める。
拡張子へパス区切りや親ディレクトリ記号を混ぜる入力も拒否する。 保存先のディレクトリを固定し、保存名はサーバ側で生成する。 拡張子の確認だけに頼らず、内容の形式も検査する。
小さく導入して確かめる
セキュリティ修正は、影響範囲が閉じた処理から導入する。 HTTPSの前提が必要な設定や、既存利用者へ影響する認証変更は、事前条件を確認してから進める。
修正後は、正しい入力だけでなく、境界を越える入力も試す。 SQLでは特殊文字を含む検索値を使う。 アップロードでは未許可の拡張子、パスらしい文字列、内容と拡張子が一致しないファイルを使う。
しろまえ殿が重視したのは、修正したという報告ではない。 入力が命令へ昇格しないこと。 保存先を選べないこと。 許可した形式だけが通ること。
境界をコードで固定すれば、後から別の画面が増えても同じ安全側の判断を適用できる。