2008年8月21日木曜日

[Security]認証・認可処理のアンチパターン

WEBアプリケーションの認証処理でやってはいけないこと、その理由をまとめます。

Refererを認証・認可に使用しない
認証・認可にRefererを使用し、判定しているサイトがあるが、RefererはWEBブラウザから送信される情報で、容易に改ざん可能であるため、認証・認可に適さない。

認証・認可にDBを利用する場合、適切なエスケープを行うこと
認証・認可において、DBに保存しているユーザ情報を使用する場合、ユーザ入力値(ユーザIDやパスワード)は必ずエスケープすること。また、プリペアード・ステートメントを合わせて使用すること。

ユーザ名とパスワードが一致するレコードの有無で認証している場合、以下のようなロジックを実装することになる。(PHPの例)
$result = pg_query("SELECT * FROM user_table
                                WHERE user_name = '".$_POST['username']."
                                AND password = '".$_POST['username']."'");
if (pg_num_rows($result) === 1) {
    ログインOK
}

ここで、ユーザ名に「'"admin';--"」を入力すると次のようなSQLが発行され、認証に成功する。
SELECT * FROM user_table WHERE username = 'admin';
-- AND password = 'any_password' ← SQLの仕様上コメント扱いとなる。

また、入力値「"'OR 1=1;--"」も認証に成功する。
つまり、ユーザ名を知らなくても認証をバイパス可能となる脆弱性を埋め込むことになるわけです。

対策として、入力値を適切にエスケープし、シングルクォーテーションやダブルクォーテーションを無効化することが重要となる。

以上です。


0 件のコメント:

コメントを投稿