SQL文字列エスケープとインジェクション防止

MySQL、PostgreSQL、SQLite、SQL ServerにおけるSQL文字列エスケープを理解しましょう。シングルクォート二重化の慣例、パラメータ化クエリ、適切なエスケープがSQLインジェクション防止に不可欠な理由を解説します。

Data Formats

詳細な説明

SQL文字列のエスケープ

SQL文字列はシングルクォートで区切られます。特殊文字 — 特にクォート — をSQL値に埋め込むには慎重なエスケープが必要です。さらに重要なのは、不適切なSQL文字列処理がSQLインジェクション(最も危険なセキュリティ脆弱性の一つ)の根本原因であることです。

標準:クォート二重化

SQL標準(ISO/IEC 9075)は、文字列内のシングルクォートを二重にしてエスケープすることを規定しています:

SELECT * FROM users WHERE name = 'O''Brien';
-- 隣接する2つのシングルクォートが1つのリテラルクォートを表す

データベース固有のエスケープ

異なるデータベースには追加のエスケープ機能があります:

MySQL: バックスラッシュエスケープ(デフォルトで有効)、NO_BACKSLASH_ESCAPES SQLモードで無効化可能。

PostgreSQL: 標準クォート二重化、C風エスケープ用E文字列、すべてのエスケープを回避するドル引用符。

SQL Server: クォート二重化のみ、Unicode用Nプレフィックス。

SQLインジェクション

エスケープされていないユーザー入力からSQLを構築すると、攻撃者が任意のクエリを実行できます。

パラメータ化クエリ(真の解決策)

文字列連結でSQLを構築しないでください。パラメータ化クエリを使用します。パラメータ化クエリはプロトコルレベルでコードとデータを分離し、入力内容に関係なくインジェクションを不可能にします。

LIKEパターンのエスケープ

LIKE 演算子は %_ をワイルドカードとして扱います。リテラルのパーセントやアンダースコアを検索するには、エスケープが必要です。

ユースケース

SQLエスケープは、データベースと対話するあらゆるアプリケーション — Webバックエンド、ETLパイプライン、管理ツール、レポートシステム、マイグレーションスクリプト — に不可欠です。パラメータ化クエリが推奨アプローチですが、エスケープルールの理解はデバッグ、ストアドプロシージャの記述、データベース関数での動的SQL構築、レガシーコードのインジェクション脆弱性監査に必要です。

試してみる — String Escape/Unescape

フルツールを開く