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;--"」も認証に成功する。
つまり、ユーザ名を知らなくても認証をバイパス可能となる脆弱性を埋め込むことになるわけです。

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

以上です。


2008年8月20日水曜日

[Java][Security]XSS対策

最近学んだ、XSS(クロスサイトスクリプティング)にたいする対策コードをまとめる。

XSSは動的にWEBページを生成するサイトの脆弱性を利用し、悪意あるスクリプトを混入させ、サイトを訪れたユーザに不利益となる操作を実行させるセキュリティ攻撃。

根本的な原因は、ユーザ入力に対するエスケープの未実施、または不適切なエスケープである。WEBアプリケーションにおいて、ユーザ入力をそのままHTMLに出力するようなロジックを使用していると、入力値に記述されたスクリプトが動作することを許容してしまう。

対策として、ユーザ入力を疑い、適切なエスケープを施すことが重要となる。

以下Javaにおける対策例。
public class HttpUtility {
    public static String escapeHTML(String str) {
        char c;
        StringBuffer returnStr = new StringBuffer();
        int length = str.length();
        for (int i = 0; i < length; i++) {
            c = str.charAt(i);
            if ( c == '<' ) {
                returnStr = returnStr.append("<");
            } else if ( c == '>' ) {
                returnStr = returnStr.append(">");
            } else if ( c == '&' ) {
                returnStr = returnStr.append("&");
            } else if ( c == '"' ) {
                returnStr = returnStr.append(""");
            } else {
                returnStr = returnStr.append(c);
            }
        }
        return new String(returnStr);
    }
}

以上です。

2008年6月10日火曜日

[設計]仕様書作成に必要なこと

本日先輩から教わった、仕様書を書くときに必要なことをまとめる。

  • 仕様用途を理解する。クライアントごとに使い方や用途が異なる。クライアントに合った設計を意識する。
  • 設計において、実装を意識することは重要だが、それ以上にメンテナンス性を意識すること。クライアント含め、システム保守に関わる人にとって有益な仕様書になっているか。
  • 趣味でシステムを作っているわけではない。人のものを作っているという意識を持つこと。
  • 構成、フォントなど、白黒でプリントしてもわかりやすいよう工夫する。
以上。