twitterにどうぞ。この広告は、90日以上更新していないブログに表示しています。2015-06-03DBにおけるウェブシステムのアカウントの権限管理とセキュリティについて下記にセキュリティに関する追記あり。読了後、そちらもチェックしてくださいユーザーと管理者アカウントがあるウェブサイトで、管理者がユーザーのパスワードをリセットできたりといった風に、アカウントによって権限が違う場合のセキュリティについての考察である。emailとパスワードでuser/adminにアクセスできるとする。1);と書きたくなる(簡略のため生パスワードを使っているが、もちろん真似してはいけない)。これは、セキュリティの観点からは好ましくない。password=$password;になると思う。password=$password;が実行され、管理者権限のアカウントが乗っ取られてしまう。Injectionがあるとする。id=$idが実行されてしまい、ユーザーが管理者に昇格してしまう。Injectionがあったとしても特権昇格ができないようなDB設計が好ましい。具体的には、userとadminのテーブルを分けるのが好ましい。仕様上idとemailはuser/admin両方で一意であることを保証しなければならないので、完全に分けることは難しい。ここでは、id_tableを使った方法ともう一つの方法を考える(あまりSQLに詳しくないので、いい方法を知っている人がいたら教えてください)。userの順に試行する。上記ではidとemailのシステム内での一意性を保証するためにid_emailテーブルを定義したが、この方法もセキュリティ上よろしくない。id=$id;のようなコードを書くことになる。id=$id;となり、管理者権限のアカウントのemailを攻撃者のものに書き換えられる可能性がある。書き換えが成功した場合、パスワードリセット機能によって管理者権限を奪われてしまう。よって、id_emailを触るときには鬼のように気をつけるか、そもそもid_emailを使わないように定義するしかない。id_emailを使わない方法についてだが、emailをuser/admin内で定義したい場合、テーブルにまたがった制約は外部キーや複合キーなどではうまく表現できないので、トリガーを使う(いい方法を知ってる人がいたら教えてください)。システム内のidはaccountテーブルを使って一意性を保証しているが、アカウント作成時にidを取得する以外では使わないので特に問題はない。外部に公開するサイトでは決してやってはならない。SQLのプレースホルダを使用し、(できれば)ペネトレーションテストも行うべきである。password=$password;で再試行する。Injectionができても管理者権限を奪うことはできない(ただし、テーブルのアクセス権限を正しく設定している場合)。パスワードの変更などについても同様である。このように、権限の異なるアカウントは特権昇格攻撃を未然に防ぐためテーブルごと完全に分けたほうがよい。言うと、そもそも1つのログイン画面で複数の権限のアカウントの管理をすること自体、実装が複雑になるのでセキュリティ上好ましくない。user_idなど関連性がないことが明らかになるように名前をつけadmin/user間のemailの重複は無視し、userとadminを完全に分けるのが、安全な設計だと思われる。Injectionは起きないので関係ないし、親クラスに相当するものがあるほうが自然だよ」という考え方もあるが、最近「権限の異なるアカウントのテーブルは必ず分けないといけない」と断言されたので、いい機会なので考えてみた次第である。断言口調で書いたものの、絶対そうでなければならないかと言われると、うーんという感じではある。おまけで一応書いておくが、生パスワードをDBに保存してはいけない。hash(hashed_password)}このようなニュアンスのものを使うべきである。ソルト」で検索してほしい。実はあまりSQLに詳しくないので、他にidとemailの一意性を保証する上手い方法があるような気がしてならないので、いい方法があったらコメントで教えてください。doの見分け方と使い方についてなどArchiveはてなブログをはじめよう!javascripterさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。