yumetodoの旅とプログラミングとかの記録

旅や登山の記録やプログラミング関連の話とかフリーソフト紹介とか

チケット購入サイトeplusのログインシステムのバグ

はじめに

知り合いに増矢馨子さんというピアニストの方がいる。

www.kaorukomasuya.com

  • Webページはどうやら更新されていない

で、今度、10/10に室内楽のコンサートがある。

web.archive.org

それのチケットがいつもと違ってチケットぴあではなくeplusだったので、会員登録をすることにしたのだ。

eplusのここがまずだめ

  • ログイン中かわからない
  • ログアウト方法がないor不明瞭
  • ログインしててもチケット購入のときはまたログインさせられる

eplus.jp

訪れればわかる、この糞of糞感。

本題

会員登録を無事に終え、チケット購入をしようとしたら、ログインを求められた、ログインしてるのに。でそれはとりあえずスルーして、ログインができない。

www.youtube.com

リアルキーボードクラッシャーやって、隣りにいた母親に怒られた。

原因

セキュリティをちょっとわかる勢C++erである私は当然KeePassでパスワードを自動生成した。しかしその自動生成したパスワードの長さが20文字だった。

eplus pass word change

パスワード登録画面には、

8文字以上16文字以下

という記述がある。

おかしい

いやちょっとまって、最初の登録の時に20文字ぶち込んでもなにもエラーにならなかったぞ、つまり入力フォームのValidationをしていない・・・?

検証したところ、登録時にいれた20文字の末尾が削られて16文字として登録されていた。

送信部分のソースコードを見てみる

幸いいかにもレガシー感漂うこのサイトのJavaScriptはminifyされていなかった。しかもHTML直書きだった。わぉ。

まずは登録フォームのほう。

$(document).ready(function() {
    // Validatorクラスのインスタンスを生成する。
    // 引数は入力チェック対象となるフォームのjQueryオブジェクト
    var validator = new Validator($('#registerMemberForm'));

    // 項目に必須属性を追加する
    var requiredFields = [];
    $('em.required').each(function() {
        if($(this).attr('epName')){
            var fields = $(this).attr('epName').split(",");
            $.each(fields,function(i,val){
                var field = $('input[name="' + val + '"]');
                if(field.length != 0){
                    requiredFields.push(field);
                }
                var field = $('select[name="' + val + '"]');
                if(field.length != 0){
                    requiredFields.push(field);
                }
            });
        }
    });

    validator.required(requiredFields);

    // ValidatorForHanyoKomokuインスタンス生成
    var validatorForHanyoKomoku = new ValidatorForHanyoKomoku("/api/v1/FTRegisterMember/hanyoKomokuCheck");

    // 確認ボタン押下
    $("#main-submit").on('click', function() {

        // 入力チェック前にアコーディオンが閉じられていた場合、入力チェック用にcss変更.非表示の場合にvalidation対象外になってしまうため
        var accordionChange = false;
        var detailsBox = $("#registerMemberForm .accordionBox .detailsBox");
        if(detailsBox.css('display') == 'none'){
            detailsBox.css('display','block');
            accordionChange = true;
        }

        // 入力チェックを実行する。
        var validError = validator.validate();
        var hanyoError = validatorForHanyoKomoku.validate();

        // cssを元に戻す
        if(accordionChange){
            detailsBox.css('display','none');

            // アコーディオン内に入力エラーがあった場合は開いて表示
            if(detailsBox.find(".errorCell").length != 0){
                accordionBoxChange(true);
            }
        }

        if(!validError || !hanyoError){
            window.scrollTo(0,dispErrorObj.offset().top);
            return false;
        }

        // 汎用項目のAJAX送信用パラメータを設定(リスト化された項目がパラメータ設定されないためここで設定.ajaxPostForFormではvalueListがString配列であることが特定できないためvalidateのjsに処理を記載)
        var param = {};
        param.soshikiHanyoKomokuSetList = validatorForHanyoKomoku.get();

        // 事前チェックでOKなら確認画面へ
        $.ajaxPostForForm(contextpath + "/api/v1/FTRegisterMember/updateCheck", $('#registerMemberForm'),param)
        .done(function(data, status, xhr, infoMessages, hasWarnings, warnMessages, hasErrors, errorMessages) {
            var res = $.parseJSON(xhr.responseText);
            if (res.isSuccess) {
                // 遷移する。
                $.doSubmit($("#registerMemberForm"), {
                    op : "startInitConfirmMemberInfo"
                });
            }
            else {
                // エラー時はダイアログ表示
                $.infoMsgBox(res.msgs[0].msg);
            }
        });
    });
    //後略
});

あれ、Validationあるじゃん。

次はパスワード変更ページ。

$(document).ready(function(){
    // 必須属性付与
    var validator = new Validator($('#updatePasswordForm'));
    validator.required([$('input[name="newPassword"]'), $('input[name="passwordConf"]')]);

    // 変更
    $('#update').click(function (e) {
        // 入力チェック
        if (!validator.validate()) {
            window.scrollTo(0,dispErrorObj.offset().top);
            return false;
        }
        $.doSubmit($("#updatePasswordForm"), {op : "startInitComplete"});
    });
});

あれ、Validationあるじゃん。ちなみに処理を追いきれなかったが、おそらく^[0-9a-zA-Z_\-@.]{8,16}$という正規表現で確認している。

しかし、会員登録ページのほうは16文字を超えても受け付けてしまう

結論

会員登録ページのValidationバグ