バインド変数って何?

プログラミング学習帳 プログラミング

sqlにはバインド変数(bind variables)というものがあります。

バインド変数とは「プログラミング言語の実行環境からDBMSへSQL文を発行する際、一部を動的に変更できる変数にする機能」=「SQL文に埋め込む変数」のことです。バインド変数を使うことで、SQL文の一部を後から設定できます。結構便利に使えるみたいです。便利なことに加えて、SQLインジェクション攻撃への有効な対応法の1つになります。

mysqlとpostgreSQLではバインド変数の設定方法が少し異なる

今回ハマったポイントです。SQL文の基本的な記述はこの2つではほとんど変わらないものと思い込んでいたのが、ミスに気付けなかったポイントですね…(一般的にはpostgreSQLの方がmysqlより厳密なSQL文が求められるとされている)。MySQLではバインド変数は”?”(プレースホルダー)で表され、PostgreSQLでは”$”で表されます。以下のクエリはIDが1の顧客の情報を取得するためにバインド変数を使用しています。尚、PostgreSQLでは同じクエリで複数のバインド変数を設定できますが、MySQLでは同じプレースホルダーを複数回使用できません。

Mysqlのケース

SELECT * FROM customers WHERE id = ?

PostgreSQLのケース

SELECT * FROM customers WHERE id = $1

バインド変数はSQLインジェクション攻撃への対応策になり得る

SQLインジェクション攻撃は、悪意のあるユーザーがWebアプリケーション上でSQL文を不正に実行することで、データベースシステムに対する攻撃を行うことです。SQLインジェクション攻撃によって、攻撃者はデータベースから機密情報を盗み出す、改ざんする、または削除することができます。

バインド変数を使用することで、SQL文内の変数の値をプログラム上で事前に定義し、その値をSQL文に渡すことができます。このようにすることで、SQL文に悪意のあるコードを挿入することができなくなります。つまり、SQLインジェクション攻撃に対して、バインド変数を使用することでセキュリティ上の脆弱性を低減することができます。

例えば以下のSQL文を考えてみましょう。

SELECT * FROM users WHERE username = '<input_value>' AND password = '<input_value>'

このSQL文には、悪意のあるユーザーが「’ OR ‘1’=’1」という文字列を入力することで、常に真となる条件を追加することができます。つまり、以下のようなSQL文が実行されます。

SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '' OR '1'='1'

これによって、すべてのユーザーの情報が取得される可能性があります。しかし、バインド変数を使用すると、プログラム上で事前に定義された変数をSQL文に渡すため、上記の攻撃を行うことができなくなります。つまり、バインド変数を使用することで、SQLインジェクション攻撃からデータベースシステムを保護することができるため、非常に重要なセキュリティ対策となります。

コメント

タイトルとURLをコピーしました