KYな雑記帳

個人的なメモ帳

SQLインジェクションについて改めて調べる

個人的な復習用

SQLインジェクションとは?

Wikipediaによると
「アプリケーションのセキュリティ上の不備を意図的に利用し、アプリケーションが想定しないSQL文を実行させることにより、データベースシステムを不正に操作する攻撃方法のこと。」

例えば、ID検索のフォームがあるとしたら、アプリケーションが用意しているSQLは以下のような感じになる。

SELECT * FROM user WHERE id=‘$ID’

このフォームに「taro’ or ‘A’=‘A」という語句が入力されると

SELECT * FROM user WHERE id=‘taro’ or ‘A’=‘A’

となり、すべてのユーザーの情報がヒットしてしまう。
驚異としては情報漏洩やデータ改ざんや不正ログインなどが考えられる。

対策

パラメータにSQL文を直接指定しない

そもそも論外の実装。
hiddenパラメータ等にSQL文をそのまま指定するという事例があったようだ。
これをしてしまうと、Webページのパラメーター改ざんでSQL自体を改ざんでき、不正利用につながる。

エスケープ処理

検索バーや入力フォームなどユーザーが入力できる機能を実装しているWebサイトに対して、特定の文字が普通の文字として解釈されるように処理することをエスケープ処理という。
不正コードの中の特定の文字列や記号を削除したり置き換えたりして攻撃を無効化できる。

例えば、「'」を「''」と置き換えることで、

SELECT * FROM user WHERE id=‘taro'' or ''A''=''A’

となり攻撃を無効化できる。

プレースホルダの利用

プレースホルダとはSQLを組み立てる仕組みの1つ。
SQL文の中の「変動する箇所」に使用され、後でそこに実際の値を機械的な処理で割り当てることで、機械的SQLが組み立てられる。
また、プレースホルダに実際の値を割り当てる処理をバインドと呼ぶが、バインドの際にエスケープ処理するものを使うことで独自のエスケープ処理を使わなくてすむようになる。

例えば、perlだと以下のようなSQLの作り方がプレースホルダ

$sth = $dbh->prepare(
"SELECT id, name, tel, address, mail FROM usr
WHERE uid=? AND passwd=?");
$sth->execute($uid, $passwd);