それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

秘密の質問ジェネレータを、pythonでぱぱっと

TL;DR

ひらがな10文字の秘密の質問の回答を作る。

python -c 'import random; print("".join([ chr(0x3042+random.randint(0,82) ) for i in range(1,10)]))';

秘密の質問って効果あるの?

秘密の質問はないよりはあったほうがマシとかいうレベルで無くても問題ないと思う。

秘密の質問は「ひらがなのみ」とかアホらしいですね。

ひらがな1文字でOKです。

f:id:takuya_1st:20190414154233p:plain

そりゃそうだ、「あなたの出身地は」という質問に「三重県 津市」のような1文字地名を1文字が許可されなときは、どう答えるのだ。

秘密の質問とかいう謎仕様に頭を悩ませる。

秘密の質問って効果あるの?→無いです。

全角ひらがなだと83文字です。

秘密の質問は8文字もありません。1文字でも5文字でも通ってしまう。 ASCIIで記号+小文字+大文字+数字=約80字が8文字以上組み合わされた通常パスワードより強度が低い。

わざわざ強度の低い文字を、しかも「現実に存在する単語」で入れさせるなんてアホらしいですね。 こういう似非セキュリティは無くなってしかるべきです。

辞書の単語をパスワードに利用するなと言うのは鉄則ですよね。

出身地の小学校の名前が十分な強度を得られるほどランダム性があるわけでもない。

何から何を守るのかも不明確

セキュリティの基本として、「何を誰から守るのか」という視点を失ってほしくないですね。

秘密の質問は誰から何を守るのでしょうか。今回の例は「イオンカード」ですが、明細の「閲覧」権限を保護はそこまで重要な情報なんでしょうか。

そもそも正直に答える必要など無い。

そもそも正直に答える必要など無い。ランダムなひらがな文字列で構わない。

というわけで、自動的に生成してしまいましょう。

f:id:takuya_1st:20190414154658p:plain

python -c 'import random; print("".join([ chr(0x3042+random.randint(0,82) ) for i in range(1,10)]))'

そもそも、ひらがなは「あーん」なのか?

ひらがなをprint してみて思うのだけど、「あーん」がひらがなでいいのだろうか。

>>> [ chr(0x3042+i) for i in range(0,190) ]
['あ', 'ぃ', 'い', 'ぅ', 'う', 'ぇ', 'え', 'ぉ', 'お', 'か', 'が', 'き', 'ぎ', 'く', 'ぐ', 'け', 'げ', 'こ', 'ご', 'さ', 'ざ', 'し', 'じ', 'す', 'ず', 'せ', 'ぜ', 'そ',
 'ぞ', 'た', 'だ', 'ち', 'ぢ', 'っ', 'つ', 'づ', 'て', 'で', 'と', 'ど', 'な', 'に', 'ぬ', 'ね', 'の', 'は', 'ば', 'ぱ', 'ひ', 'び', 'ぴ', 'ふ', 'ぶ', 'ぷ', 'へ', 'べ', 
'ぺ', 'ほ', 'ぼ', 'ぽ', 'ま', 'み', 'む', 'め', 'も', 'ゃ', 'や', 'ゅ', 'ゆ', 'ょ', 'よ', 'ら', 'り', 'る', 'れ', 'ろ', 'ゎ', 'わ', 'ゐ', 'ゑ', 'を', 'ん', 'ゔ', 'ゕ',
 'ゖ', '\u3097', '\u3098', '゙', '゚', '゛', '゜', 'ゝ', 'ゞ', 'ゟ', '゠', 'ァ', 'ア', 'ィ', 'イ', 'ゥ', 'ウ', 'ェ', 'エ', 'ォ', 'オ', 'カ', 'ガ', 'キ', 'ギ', 'ク', 'グ',
 'ケ', 'ゲ', 'コ', 'ゴ', 'サ', 'ザ', 'シ', 'ジ', 'ス', 'ズ', 'セ', 'ゼ', 'ソ', 'ゾ', 'タ', 'ダ', 'チ', 'ヂ', 'ッ', 'ツ', 'ヅ', 'テ', 'デ', 'ト', 'ド', 'ナ', 'ニ', 'ヌ', 
'ネ', 'ノ', 'ハ', 'バ', 'パ', 'ヒ', 'ビ', 'ピ', 'フ', 'ブ', 'プ', 'ヘ', 'ベ', 'ペ', 'ホ', 'ボ', 'ポ', 'マ', 'ミ', 'ム', 'メ', 'モ', 'ャ', 'ヤ', 'ュ', 'ユ', 'ョ', 'ヨ', 
'ラ', 'リ', 'ル', 'レ', 'ロ', 'ヮ', 'ワ', 'ヰ', 'ヱ', 'ヲ', 'ン', 'ヴ', 'ヵ', 'ヶ', 'ヷ', 'ヸ', 'ヹ', 'ヺ', '・', 'ー', 'ヽ', 'ヾ', 'ヿ']

あーんだと次の3文字が欠損する

 'ゔ', 'ゕ', 'ゖ',

他にも、ダッシューは?波線〜は?

長音、ダッシュとハイフンの違いはどうするんだろうか。

>>> hex(ord('ー'))
'0x30fc'
>>> hex(ord('―'))
'0x2015'
>>> hex(ord('−'))
'0x2212'

こんなあやふやでフワっとした「秘密の質問」ってもう無くていも問題ないと思うんですよね。

さて、イオンカードの場合を見てみよう。

ああ、やっぱり「あーん」ですね。

f:id:takuya_1st:20190414153607p:plain

元になってる日本語判別はなんだろう jquery の野良プラグインですね。お疲れ様です。

f:id:takuya_1st:20190414153803p:plain

正規表現エンジンで  /あ-んー\s/ ですか。それならブラウザのinput:invalidate のrequired pattern= の組み合わせで十分なんじゃないですかね。。。

判定条件はこれだった。

"hiragana": {
                    "regex": /^[ぁ-んー\s]+$/,
                    "alertText": "* ひらがなのみで入力してください。"
                },

うーん・・・これでいいのか?

しかも、この判定だと、半角スペースを「ひらがな」として通してしまいませんか?

こうなってくると、他の判定正規表現、たとえばemail アドレスの判定も疑わしいですね。

結論:自動生成使用。

あーん だと抜ける文字がある。ハイフン長音の違いでユーザーに不親切になる。このjQuery野良プラグインは半角スペースを通してしまう。

秘密の質問はやっぱりいらない。

自動生成で十分だ。

追記:秘密の質問のパターン甘い

こんな、適当な秘密の質問でも通ってしまう

f:id:takuya_1st:20190414153658p:plain

ほんと、なんのためにあるんですかね。

追記:しかも平文で保存される。

最大20文字とか制限があるんでオカシイなとおもったら、やっぱり平文保存だった。

最大文字数が制限されいるとき、殆どの場合で「データベースのカラム長」だと思われる。つまり保存は平文である。

変更画面でもとの秘密の質問が表示される。うーんここは平文で保存する必要があるのかな?ハッシュ化してないんだね。

f:id:takuya_1st:20190414160508p:plain