"Shade検索"Wiki

アップローダ ゲストモードのパスワード

CGI/マルチアップローダに戻る

制限ユーザー


ver.1.51まで、登録ユーザーからファイルの受け渡し相手に知らせるURLは、登録ユーザーがログインするURLと同じものを送っていました(ユーザーIDとパスワード含む)。
このため、ファイルの受け渡し相手も登録ユーザーと同じように、ユーザー登録の変更、抹消など、登録ユーザーができる操作がすべてできてしまっていました
信頼できる相手との一対一の関係なら、これでもいいのかもしれませんが、多数の相手にURLを知らせる必要がある場合などは、管理上これでは問題があるかなと思い、
1.52では受け渡し相手には登録ユーザーとは違うURLでログインしてもらうことにしました。

結果的にCGI内部で結構ややこしい処理をすることになったので、忘れないようにまとめておきます。

ファイルの受け渡し相手を制限ユーザー(ゲストモード)とします。制限ユーザーにも、一応アクセス制限が必要です。ユーザーが登録したアカウントの場合、専用ディレクトリ名そのものが暗号化されるので、
専用ディレクトリ名を知っている相手には特にパスワードによる制限は必要ないかなとも思いましたが、
管理人が作成したアカウントの場合、専用ディレクトリ名が一般的な、容易に想像できる名前になる可能性があるので、ここはやはりパスワードによるアクセス制限をすることにしました。
ユーザー登録時にユーザー用パスワードとは別に、制限ユーザー用のパスワードも設定することにすればいいのでしょうが、これはちょっと面倒です。
このパスワードの条件としては、

  1. ユーザーIDと関連づけられているが、
  2. 登録ユーザーが使用するパスワードとは違うもので、
  3. なおかつそのパスワードから登録ユーザーのパスワードが推定できない

ものにする必要があります。

cryptされたパスワード


この条件を満たす方法として、文字列を暗号化するcryptを使うことにしました。
cryptは一方通行の暗号化を行うもので、このCGIでもすでにパスワード認証に使用しています。
cryptを使ったencrypt関数で暗号化し、decrypt関数で照合を行います。(decryptという名前になっていますが、復号ではなくあくまでも照合です)
$passが元のパスワード、$crypt_passが暗号化されたパスワードとすると、$passをencrypt関数に渡して、作成された$crypt_passを保存します。
照合は、cryptの第1引数に$pass、第2引数に$crypt_passを渡して、返値が$crypt_passに等しい場合、$crypt_passは$passから暗号化されたものであることがわかるので、照合に成功
返値が$crypt_passと等しくなければ照合できなかったと判断します。$crypt_passから元の$passを簡単に知ることはできないので、CGIでのパスワード照合では$passは保存せず、
$crypt_passだけを保存して照合処理をするものが多いです。万一$crypt_passが外に漏れても、容易にパスワードが知られないようにということだと思います。
$crypt_passでは照合をパスすることはできないからです。

このCGIでも照合用に$crypt_passを保存していますが、実は生のパスワード$passも保存しています。
これは主に、管理人が登録したユーザーにメールなどでパスワードを知らせる必要のためです。
※生のパスワードを保存するのはリスクがあるので、ランダムな文字列で外部から存在が察知されにくいパスワード保存用ディレクトリを作り、その中にブラウザで開けないはずのcgiファイルとして保存するという対策を取っています。

制限ユーザーは逆照合


生のパスワードを保存しているという前提の元、制限ユーザーに使用するパスワードとして、この暗号化された$crypt_passを使用することにしました。
照合は、通常のパスワード照合とは逆で、第1引数に$crypt_pass、第2引数に$passを使用することになります。$crypt_passはランダムな文字列になりますが、
制限ユーザーにはURLに含めて渡すので、特にパスワードとして意識する必要はありません。
$crypt_passはユーザー登録時にも保存されているので、それをそのまま使ってもいいのかもしれませんが、メール送信時にオリジナルのパスワードからその都度生成することにしました。
なので、同じ登録ユーザーから送っても、送るたびに違う暗号化パスワードになります。*1

このCGIでは処理を行うたびにユーザーIDとパスワードの照合を行っています。通常のパスワード照合ではpassというキー名でパスワードを渡していますが、
制限ユーザーのパスワード照合はgpassというキー名で渡すことにしました。URLでいうと、通常はpass=guest、制限ユーザーはgpass=ugj4xZq6XMGOAのような感じになります。
CGIはpassを送ってきた相手には通常のログイン処理、gpassを送ってきた相手には制限ユーザー(ゲストモード)のログイン処理を行うことになります。
制限ユーザーの場合は、ユーザー設定、ディレクトリの作成、ディレクトリの移動、メール送信が無効になりますが、その分岐処理はとりあえずgpassを送ってきているかどうかで判断することにしました。

制限ユーザーのディレクトリ


また、制限ユーザーは、登録ユーザーがメール送信フォームを開いたときにアクセスしていたディレクトリのみにアクセス可能ということにしていますが、登録ユーザーの専用ディレクトリへのアクセス制限はかなり甘いです。
たとえば、登録ユーザーの専用ディレクトリが./upload/usr_root/ohnuIBqbUYI5oで、そのサブディレクトリの./upload/usr_root/ohnuIBqbUYI5o/subからURLお知らせメールを送ると、
メールを受け取った制限ユーザーは./upload/usr_root/ohnuIBqbUYI5o/subにアクセス出来ますが、URLを少し修正するだけで./upload/usr_root/ohnuIBqbUYI5oにもアクセスできてしまいます。
もちろん、他の登録ユーザーの専用ディレクトリには、容易にアクセスは出来ません。(絶対とはいえませんが・・・)

制限ユーザーのディレクトリ作成、ディレクトリ移動機能を無効にしたのは、セキュリティのためというより、なるべく機能をシンプルにしたかったからなので、
とりあえずこのままでもいいかなと思っていますが、どうなんでしょう。

ファイルダウンロードのURL


ファイルのダウンロードの際もパスワード照合を行っています。これも当然制限ユーザーは暗号化パスワードで逆照合することになります。
登録ユーザーは当初は生のパスワードでダウンロードしていましたが、ver.1.56から登録ユーザーも暗号化パスワードを使用するよう変更しました。
管理者については、いまだに生のパスワードでダウンロードするようになっています。

このため、生パスワードが保存されないというバグが発生すると、登録ユーザーはファイルのダウンロードに失敗するけど、管理者はできてしまうという現象が起きてしまいます。

おそらく使う必要のない裏技(^^;;


単にCGIで書き出すダウンロードのURLが違うだけで、ファイルのダウンロード処理としては、どちらでも(生パスでも暗号化パスでも)行えるからですが、
これは管理者だけでなく登録ユーザでも同じです。
暗号化したパスワードを使ったダウンロードに失敗したら、ダウンロードURLのうち、gpass=暗号化パスワードの部分をpass=生パスワードに変更すればダウンロードできるはずです。
もちろんユーザー設定変更可能なら、ユーザー設定を上書きして生パスワードを復元する方が早いですが、管理者が登録したアカウントでログインしているときに、ダウンロードできなかったらこの方法が使えるかもしれません。

*1保存された$crypt_passを使うのどちらがより安全なのかはよくわかりません。



2567


>>2011/05/29 17:30:40更新>>