ログインプログラムのセキュリティを考える


多くの企業アプリケーションでは、ユーザーのログインと検証が一般的に存在します.ユーザデータ格納の方式としては、データベース格納、LDAP/AD、ファイル格納などが一般的である.
 
リレーショナル・データベースが発達した時代には、機密性とセキュリティの面だけでファイル・ストレージは基本的に考慮されなくてもよいことは明らかです.
 
データベースはユーザー資料を格納し、現在流行している格納方式であり、ソフトウェア開発者はユーザー名と対応するパスワードをデータベースの2つのフィールドに直接格納することができる.次に、次のようなSQL言語でユーザー検証を実行できます.
select * from user where username='name' and password='password';

UI設計では,ユーザIDを入力し,パスワードボックスでパスワードを入力するテキストボックスを一般的に提供する.次に、変数転送によってserver側に転送されて検証されます.サービス側の類似した検証SQLスクリプトは、次の場合があります.
String sql = "select * from user where username='" + userName + "' and password='" + password + "'";

 
返されたデータセットのsizeにより、現在のユーザが存在するかどうかを判断し、ユーザをチェックして検証します.
 
 
どう見ても、すべてが自然で、合理的です.意外にも、安全上の危険性が発生しました.
1.ユーザパスワード原文記憶
 
データベースはずっと秘密の部分ですが、パスワードをpasswordというフィールドに正直に記入すると、ユーザーのパスワードはデータベース管理者や第三者がデータベースにログインしているパスワードを知っているユーザーに赤裸々に露出します.現実には、そのような誠実なユーザーが不足せず、自分の銀行パスワード、金庫パスワードなどを自分のログインパスワードとして使用しています.このすべては、あなたに企んでいる別の人の重要な資料になったかもしれません.
だから、いずれにしても、ユーザーのパスワードを直接データベースに保存しないでください.MD 5、SHAなどのパスワード暗号化方式で暗号化してからpasswordフィールドに保存することができます.
ユーザーのパスワードをなくしたら、パスワードを取り戻すにはどうすればいいですか?簡単で、新しいパスワードを直接作成し、ストレージを暗号化し、ターミナルユーザーに提供します.
 
2.SQL文注入の脅威
上の例では、UIのユーザー入力ボックスに「name'and'1'='1」と入力すると、どのような結果になりますか?試してみると、データベース内のすべてのユーザーデータを取り出すことができます.プログラムの処理が適切でない場合、パスワード検証を迂回する近道を与えている可能性があります.
これはまだ軽いですが、「name';delete from user;select*from user where'1'='1」と入力すると、どのような結果になりますか?あなたのユーザー資料はすべて悪意を持って削除されました.データベースは安全ですか?
このようなSQL注入の問題をどのように解決しますか?2つの側面から入手できます.
1). 文字クライアントまたはサービス側の検証、入力したユーザー名の長さ、および特殊な文字が含まれているかどうかを確認します.
2). あなたのSQL文の構造方法を修正して、直接文字列の接続の方式を採用してあなたのSQL文を構築しないでください、あなたは他の方式を採用することができます.Hibernateのように、hsqlのクエリー方式を使用して直接クエリーするのではなく、プライマリ・キーの位置決め方式でこのUserオブジェクトを取得し、パスワードが正しいかどうかを判断することができます.また、criteria、queryオブジェクトを作成する方法で、検証を直接クエリーできます.次のようになります.
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(User.class);
detachedCriteria.add(
        Restrictions.eq("username", userName)).add(
        Restrictions.eq("password", password));
List userList = this.hibernateTemplate.findByCriteria(detachedCriteria);
if (userList.size() == 1) {            
    return (User) userList.get(0);
} else {
    return null;
}

 
ここでは,暗号クライアント暗号化,httpsのセキュリティ接続など,接続伝送のセキュリティ問題は考慮しない.
 
LDAPとADについては、非常に安全で効率的で柔軟なユーザー検証手段と言えるでしょう.関連するLDAPまたはADを接続するプログラムは、ネットワーク上で一般的に関連するコードを収集することができます.