章: 第5章: Web・DB・セキュリティ
DBに「パスワード」をそのままの文字列で保存していませんか?それは漏えい時に壊滅的な被害を招きます。
問題と解決策
パスワードを平文でDBに保存すると、もしDBが漏えいした場合、全ユーザーのパスワードが一瞬で攻撃者の手に渡ります。ユーザーが他サービスでも同じパスワードを使っていれば、被害は連鎖します。
解決策はハッシュ化です。password_hash() でハッシュ化し、password_verify() で比較する—— この2関数を使えば、平文を保存せずに安全な認証が実現できます。bcryptアルゴリズムが自動で適用され、ソルトも自動付与されます。
ハッシュ手法の比較
| 手法 | 安全性 | 推奨度 |
| 平文保存 | 最低(漏えい即アウト) | ❌ 絶対NG |
| MD5 / SHA1 | 低(高速すぎて総当たりに弱い) | ❌ 非推奨 |
| SHA256(ソルトなし) | 低〜中(レインボーテーブル攻撃に弱い) | ❌ 非推奨 |
password_hash() (bcrypt) |
高(低速設計+自動ソルト) | ✅ 推奨 |
チェックポイント:
password_verify($input, $hash)で照合していますか?ハッシュ同士を===で比較するのは間違いです。ハッシュには毎回異なるソルトが含まれるため、同じパスワードでも毎回異なるハッシュ値になります。
コードサンプル
<?php
$hash = password_hash('secret123', PASSWORD_DEFAULT);
var_dump(password_verify('secret123', $hash));
まとめ & 次のステップ
- パスワードは必ず
password_hash()でハッシュ化してからDBに保存します PASSWORD_DEFAULTを使うと推奨アルゴリズム(bcrypt)が自動で適用されます- 認証時は
password_verify()で照合し、ハッシュを直接比較してはいけません - MD5やSHA1はパスワード保存には絶対に使わないでください
次回は CSRF対策 — 意図しないリクエストをトークンで防ぐ仕組みを学びます。