安全でないパスワード保存、または高速ハッシュの使用

安全でないパスワード保存、または高速ハッシュの使用

説明

パスワードを平文、またはMD5やSHA系などの高速な汎用ハッシュで保存すると、漏えい時にオフラインの推測攻撃を受けやすくなります。

想定される影響

  • データベースやログの漏えいによって、アカウントを乗っ取られる危険が高まります。
  • 高速ハッシュはGPUを使った大量の推測に特に弱い方式です。

対処方法

  • bcrypt、scrypt、Argon2id、PBKDF2など、計算コストを調整できるパスワード専用のハッシュ方式を使ってください。
  • 既存の高速ハッシュは、ログイン成功時にパスワードを再ハッシュして段階的に置き換えてください。

例

パスワードの保存方式だけを比較する抜粋です。bcryptのコストはデプロイ環境で測定し、72バイトを超える入力はエラーとして処理してください。

変更前

go
user.SetPasswordHash(sha256.Sum256([]byte(password)))

変更後

go
package example

import "golang.org/x/crypto/bcrypt"

type passwordHashStore interface {
    SetPasswordHash([]byte)
}

func storePassword(user passwordHashStore, password string) error {
    hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
    if err != nil {
        return err
    }
    user.SetPasswordHash(hash)
    return nil
}

解説:

  • 変更前: 平文ではパスワードがそのまま露出します。高速なSHA/MD5ハッシュでは、データベースやログの漏えい後に大量の候補をオフラインで試せます。
  • 変更後: bcryptの計算コストによって、漏えい後の推測攻撃を高コストにします。ハッシュ生成のエラーを確認するため、長すぎるパスワードなどのエラー時にnilや無効なハッシュを保存しません。

参考資料