前回:やられアプリ BadTodo - 16 バッファオーバーフロー - demandosigno
これまでに「IPA 安全なウェブサイトの作り方 第7版」の11項目を検査してきました。
BadTodoは「ウェブ健康診断仕様」の診断項目も網羅しています。 この内、安全なウェブサイトの作り方と重複していない残りの2項目(認証・クローラへの耐性)について検査します。
認証
「ウェブ健康診断仕様」p.16より。
パスワードの強度とログアウト時の挙動について、次の6項目を確認します。
1.パスワードの最大文字数が8 文字以上確保されているか
2.パスワードの文字種が数字のみ、英字のみに限定されていないか
3.パスワードが入力時に伏字になっているか
4.パスワード間違いの際のメッセージは適切か
5.ログアウト機能はあるか、適切に実装されているか
6.意図的に 10 回パスワードを間違える
1.パスワードの最大文字数が8 文字以上確保されているか
「8文字未満」の場合、強度が弱く問題ありとされます。
「マイページ」→パスワード「変更」画面から、パスワードを変更してみます。「a」1文字の入力としました。
変更をクリックすると「パスワードは4文字以上で指定してください」と出ました。
1,2,3文字では同様のエラーでしたが、4文字「aaaa」で登録することができました。
8文字未満であるため問題あります。
「マイページの全体情報変更画面」「新規会員登録画面」でも同様に4文字で登録可能でした。
このように(changepwddo.php, editprofiledo.php, adduser.php)の3リクエストを確認する必要がありますが、以降はパスワード変更画面での例を示します。
2.パスワードの文字種が数字のみ、英字のみに限定されていないか
「数字のみ、英字のみの場合」問題ありとされます。
「aaaa」「1111」どちらでも登録できました。問題ありです。
としてしまいましたが「限定されていないか」でした。「aa11」「aa-11*」などでも登録できましたので、限定されているというわけではないのでOKにします。
この辺りの認識が曖昧ですので後日調べます。
3.パスワードが入力時に伏字になっているか
「伏字になっていない場合」問題ありとされています。入力時の画面を肩越しに覗かれるなどして漏洩する可能性を問題視しています。
「新規会員登録画面」伏字になっています。問題ありません。
「パスワード変更画面」「マイページ変更画面」問題ありません。
「ログイン画面」伏字になっていません。問題ありです。
ただ「実際問題後ろから覗き込む人などまずいない」「その気になればキーボードからでも読み取れる」「入力ミスの多発」からの「安易なパスワード設定」に繋がるなど、隠せばよいとは一概には言えません。
そこで巷で見かける方法としては、伏字にした上で「パスワードを表示する」という項目にチェックを入れると文字列を確認できるようになっていることが多いです。
(ただ、ブラウザの機能としてではなくアプリケーション側で「パスワード表示ボタン」を独自実装するのは危険が伴います)
4.パスワード間違いの際のメッセージは適切か
「ユーザ ID とパスワードのどちらが間違いか分かるようなメッセージの場合」問題ありです。
ログイン時、ID、パスワードをそれぞれ間違ってみます。
「そのユーザーは登録されていません」「パスワードが違います」と出ました。
これらのメッセージから「そのIDは存在しない」と確定でき攻撃者へのヒントとなります。一概には言えませんが、一般的には「IDまたはパスワードが違います」と表示するのが良いとされています。
(ログインIDとパスワードがそれぞれ1万通りある場合、IDの間違い(存在しないID)が分かるなら2万通りの探索で済みますが、双方分からない場合1万×1万=1億通りすべて試すことになります)
(しかしこれもまた「どちらが間違ったのか分からないのは不便」「そもそもログインIDが公開されているサイトには無意味」なため、IDの確認を先に済ませその後にパスワードの確認を行うといったようにIDとパスワードを別々に入力させるサイトが増えています)
(後述の徳丸さんの講演資料「セキュリティの都市伝説を暴く」を参照)
5.ログアウト機能はあるか、適切に実装されているか
「ログアウト機能がない、あるいはログアウト後「戻る」ボタンでセッションを再開できる場合」問題ありです。
「ログアウト機能」あります。
しかしログアウト後「戻る」ボタンをクリックすると
操作を再開することができました。
6.意図的に 10 回パスワードを間違える
「アカウントロックされない場合」問題ありです。
ログイン時にパスワードを10回以上間違えても「パスワードが違います」と出るだけで、アカウントロックはされませんでした。問題ありです。
その他(パスワードが6文字までしか登録されない)
admin(管理者)として会員一覧を見てみると、ID: wasbookのパスワードが wasbook ではなく wasboo と一文字少なく何かおかしいと感じます。
試しにユーザ test4:パスワード「password」で登録してみましたが「passwo」となりました。
どうやら表面上は8文字まで入力できるとなっていますが実際には6文字しか登録されていないようです。
またログイン時はパスワードの6文字目まで合っていれば7文字目以降が間違っていてもログインできます。
ソースコードを見てみると adduser.php にて mb_substr関数で先頭から6文字だけ取り出しています。PHP: mb_substr - Manual
<?php $pwd = mb_substr(filter_input(INPUT_POST, "pwd"), 0, 6);
DB上も varchar(6) と、格納できる最大文字数が6バイトとなっています。
MariaDB [todo]> show columns from users; +--------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+--------------+------+-----+---------+-------+ | id | int(11) | NO | | NULL | | | userid | varchar(64) | NO | | NULL | | | pwd | varchar(6) | NO | | NULL | |
徳丸さんによると、このような実装は古いシステムでたまに見かけるという。昔はパスワードが6桁までというサイトが結構あり、表面上は7文字以上入力できても切り詰めてしまう仕様になっていることがある。
なお、入力できるパスワードの長さに決まったものはないが、現在では一般に「8文字以上」が最低ラインとされているという。
え? 同じIDで登録できる? コンビニ証明書で話題「同時処理」の危険性:“典型的やられサイト”で学ぶセキュリティのワナ(1/4 ページ) - ITmedia NEWS
同じID名を同時に登録した場合などに起きる「レースコンディション問題」についても後日確認したいです。
参考にした資料
www.slideshare.net