Skip to content

MS_SQLInjectionCountermeasures

nishi_74322014 edited this page Sep 1, 2026 · 1 revision

SQLインジェクション対策の実装方針

概要

  • ユーザ入力などからインジェクションを行い、攻撃者の意図する SQL を実行する。
  • 対策不十分だと、ユーザの個人情報などが漏洩する
    ダメージの大きな攻撃を受ける可能性がある。

対策

基本

基本的にパラメタライズド・クエリを使用する。

補足(なぜパラメタライズド・クエリが決定打なのか): 参考に挙がっている
「SQL 文を組み立てないことにあり」という表現がすべてで、
パラメタライズド・クエリは
SQL の構文木を先に確定させ、値を後から流し込む方式である。
値がどんな文字列であっても構文として解釈されないため、
エスケープの漏れという概念そのものが無くなる。

// NG(文字列連結)
cmd.CommandText = "SELECT * FROM Users WHERE Id = '" + id + "'";

// OK(パラメタライズド・クエリ)
cmd.CommandText = "SELECT * FROM Users WHERE Id = @Id";
cmd.Parameters.Add("@Id", SqlDbType.NVarChar, 50).Value = id;

ORM(Entity Framework、Dapper など)を使う場合も、
LINQ や名前付きパラメタを使っていれば自動的にこの形になる。
危ないのは FromSqlRaw / ExecuteSqlRaw
文字列連結を渡すケースである。

例外

パラメタライズド・クエリを使用しない場合、

  • 以下の情報を参考にして、適切にサニタイジングを行う。
  • 脆弱性診断ツールを使用して、念入りにテストする。

補足(パラメタ化できない箇所がある): 「例外」に該当するのは、
値ではなく識別子や構文を動的に決めたいケースである。

対象 パラメタ化
WHERE 句の値、INSERT の値 できる(必ずこちらを使う)
テーブル名 / 列名 できない
ORDER BY の列、ASC/DESC できない
IN (...) の要素数が可変 要素ごとにパラメタを作れば可能

パラメタ化できない箇所は、**エスケープではなく
許可リスト(ホワイトリスト)**で対処する
(「ソート列は name / date / id のいずれか」と決め打ちし、
それ以外は受け付けない)。
「適切にサニタイジング」よりも確実で、実装も単純になる。

補足(被害を抑える構成): アプリが接続する DB ユーザーには
必要最小限の権限しか与えない(テーブルの所有者権限や
xp_cmdshell などは論外)。
インジェクションを完全に塞ぐのが第一だが、
万一通ったときに 全テーブルを読まれる / OS コマンドを
実行される
状態にしておかないことも重要である。

参考

本 Wiki 内


Tags: テスト

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally