👅

[フロントエンド]新規登録時のパスワードのルールをOWASP/ASVSに準じて実装してみよう

2023/06/11に公開

はじめに

よくwebサイトで何かしらのアカウントを作成する際
「パスワードは最低8文字以上で、英大文字・英小文字・数字それぞれを最低1文字ずつ含む必要があります」
のような文言があるかと思います。

これってそもそもなんでそんな制約がいるのだろうかと考えてしまいました。
いや、分かりますよ。制約がなかったら

a

とか

password
みたいな適当なパスワードで登録されるから、セキュリティ的に全然安全じゃない。というのは直感的には理解できます。

IPAのサイトを見に行くと次のようなことが書かれていますしね

https://www.ipa.go.jp/security/chocotto/index.html

安全なパスワードとは

  • 最低でも10文字以上の文字数で構成されている。
  • パスワードの中に数字や、「@」、「%」、「"」などの記号も混ぜている。
  • パスワード内のアルファベットに大文字と小文字の両方を入れている。
  • サービスごとに違うパスワードを設定している。

(ほとんどのサイトだと8文字以上~って書かれてるからIPAの安全なパスワードの条件を満たせていないんじゃね・・・?)
...みたいな野暮なことは一旦脇に置きましょう。

IPAのガイドライン通りのパスワード強度が作られてるからイイッショ!となってもいいのですが、どうせならIPAではなく、アメリカの非営利組織であるOWASP(Open Web Application Security Project)の推奨しているパスワード強度に従って作ってみるのもいいかもしれません。

...

..

.

作ってみましょう!

IPAでの安全なパスワード条件とOWASP/ASVSでの条件がどう違っているのか、を知るだけでも視野が広がると思いますしね。

OWASP(Open Web Application Security Project)ってなに?

https://owasp.org/about/

OWASP/ASVSで推奨されているパスワード強度は?

https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html
の中で紹介されている

https://github.com/OWASP/ASVS/blob/master/4.0/en/0x11-V2-Authentication.md#v21-password-security

に書かれている要件を引用して置きます。ちなみにASVSとは

OWASP Application Security Verification Standard (ASVS) プロジェクトの主な目的は、あらゆる種類の Web アプリと Web サービスにオープンなアプリケーション セキュリティ標準を提供することです。 ※Google翻訳
https://github.com/OWASP/ASVS#introduction

と書かれていますね。はい。

・・・

以下、引用元の一覧をGoogle翻訳した日本語に置き換えて書いておきます

# Description L1 L2 L3 CWE NIST §
2.1.1 ユーザーが設定したパスワードの長さが、(複数のスペースを結合した後) 少なくとも 12 文字であることを確認してください。 (C6) 521 5.1.1.2
2.1.2 少なくとも 64 文字のパスワードが許可され、128 文字を超えるパスワードは拒否されることを確認します。 (C6) 521 5.1.1.2
2.1.3 パスワードの切り捨てが実行されていないことを確認します。ただし、連続する複数のスペースは単一のスペースに置き換えることができます。 (C6) 521 5.1.1.2
2.1.4 スペースや絵文字などの言語に依存しない文字を含む、印刷可能な Unicode 文字がパスワードで許可されていることを確認します。 521 5.1.1.2
2.1.5 ユーザーがパスワードを変更できることを確認します。 620 5.1.1.2
2.1.6 パスワード変更機能にユーザーの現在のパスワードと新しいパスワードが必要であることを確認します。 620 5.1.1.2
2.1.7 アカウント登録、ログイン、およびパスワード変更中に送信されたパスワードが、ローカルで (システムのパスワード ポリシーに一致する最も一般的な上位 1,000 個または 10,000 個のパスワードなど) または外部 API を使用して、一連の侵害されたパスワードと照合されていることを確認します。API を使用する場合は、ゼロ知識証明またはその他のメカニズムを使用して、プレーン テキストのパスワードが送信されたり、パスワードの侵害ステータスを検証するために使用されたりしないようにする必要があります。パスワードが侵害された場合、アプリケーションはユーザーに侵害されていない新しいパスワードを設定するよう要求する必要があります。 (C6) 521 5.1.1.2
2.1.8 ユーザーがより強力なパスワードを設定できるように、パスワード強度メーターが提供されていることを確認します。 521 5.1.1.2
2.1.9 許可される文字の種類を制限するパスワード構成ルールがないことを確認してください。大文字、小文字、数字、特殊文字を使用する必要はありません。 (C6) 521 5.1.1.2
2.1.10 定期的な資格情報のローテーションやパスワード履歴の要件がないことを確認します。 263 5.1.1.2
2.1.11 「貼り付け」機能、ブラウザのパスワード ヘルパー、および外部パスワード マネージャーが許可されていることを確認します。 521 5.1.1.2
2.1.12 ユーザーが、マスクされたパスワード全体を一時的に表示するか、これが組み込み機能としてないプラットフォームでパスワードの最後に入力した文字を一時的に表示するかを選択できることを確認します。 521 5.1.1.2

うぉ!多い・・・

いくつか自分が気になったところを確認していきます

2.1.1 ユーザーが設定したパスワードの長さが、(複数のスペースを結合した後) 少なくとも 12 文字であることを確認してください。

結構多いですね。IPAだと10文字でしたが・・・
ただ引用元の https://github.com/OWASP/www-project-proactive-controls/blob/master/v3/OWASP_Top_10_Proactive_Controls_V3.pdf を見に行くと10文字とか書いてあったり、チートシートの方を見ると8文字と書いてあったり、バラバラになってますね・・・

ただ最低文字数を8文字以上にするならMFAは必須にしなさいと書いてあるようでした。

2.1.2 少なくとも 64 文字のパスワードが許可され、128 文字を超えるパスワードは拒否されることを確認します

パスワードの最大長の話ですね。最大文字数についてはIPA側の方には書かれていませんでしたね。
long password Denial of Service attacksというものを防ぐためらしいです。

https://www.acunetix.com/vulnerabilities/web/long-password-denial-of-service/

2.1.8 ユーザーがより強力なパスワードを設定できるように、パスワード強度メーターが提供されていることを確認します。

たまに他のサイトに見に行くとありますね、パスワードの文字数とかによってグラフが伸び縮みしたりするやつ

強度の判定には、チートシートに記載のある zxcvbn-ts
を推奨していますね。俺の考えた最強のパスワード強度判定を実装するのはあまりよろしくないのでやめましょう

2.1.9 許可される文字の種類を制限するパスワード構成ルールがないことを確認してください。大文字、小文字、数字、特殊文字を使用する必要はありません。

冒頭でもありましたが、かなりの割合で「パスワードは最低8文字以上で、英大文字・英小文字・数字それぞれを最低1文字ずつ含む必要があります」のような制限がかかってるサイトがあります。Zennの記事でもこれらの制限をつけるために正規表現でごにょごにょやっている記事もたくさんありますね。

https://pages.nist.gov/800-63-3/sp800-63b.html

のページの5.1.1.2にも書いてありますね

Verifiers SHOULD NOT impose other composition rules (e.g., requiring mixtures of different character types or prohibiting consecutively repeated characters) for memorized secrets. Verifiers SHOULD NOT require memorized secrets to be changed arbitrarily (e.g., periodically). However, verifiers SHALL force a change if there is evidence of compromise of the authenticator.

2.1.11 「貼り付け」機能、ブラウザのパスワード ヘルパー、および外部パスワード マネージャーが許可されていることを確認します。

ペースト禁止のサイトまじでゆるさねぇえぇえええええぞおおおおおおおおおお

自分が気になったのはこのくらいです。

実装

技術スタック

  • Svelte Svelteはいいぞ!!

とりあえず実装してみましょう!
以下注意点 and 言い訳です

  • CSSは適当
    • CSSは難しすぎるので仕方ないです
  • バックエンドが絡む実装は省きます
  • コードが汚いのは許してください
    • 記事と並行してきれいなコードを書くのは恐ろしく大変なので
    • 汚いな、という自覚はあります
    • いちいちファイル作るのがめんどくさかったので1ファイルにほとんど収めちゃいまいた
      • 仕事では絶対にやめましょう。嫌われます。

書いてみた

Stackblitzに書いてみました

画面はこんな感じです

パスワードに「名前 + 誕生日」のような推測されやすいワードを入れると、zxcvbnのパワーによって弾かれます

最後に

OWASPでの推奨されているパスワード強度はかなり強力です。GoogleやAppleなんかよりもかなり強い印象を受けました。
国内サービスならばIPAのガイドラインに準拠されてれば炎上することは多分ないかな?とか個人的に思ったりします。
あとこういったパスワードの要件はステークホルダーとのコミュニケーションをうまくやる必要があります。彼らからすれば、強力すぎるパスワード要件はユーザー離脱につながるのではないか、と危惧してしまうからですね。
もしコミュニケーションがうまく行かなかった場合は心のなかで
(๑癶ω癶๑)< ニチャァ
としましょう。

知見だ、と思ってくれた方はぜひ♥をお願いします!

では!!

余談

ぶっちゃけ新規サービスならGoogle認証やApple認証に完全に任せたり、Email onlyの認証にしたりしたほうが絶対いいだろうな、とか思います。身も蓋もない。

Discussion