事例・基礎知識
なぜ7payは失敗したのか?AIで爆速開発する時こそ見直したい『認証フロー』の落とし穴
サービス開始わずか3ヶ月で終了した7pay。その原因となった「認証の不備」は、実はAI任せで開発していると陥りやすい罠でもあります。個人開発でも絶対に省略してはいけない認証の最低ラインを解説します。
2019年7月1日、セブン-イレブンが満を持してリリースしたスマホ決済サービス「7pay」。しかしサービス開始からわずか2日後には不正アクセスの報告が殺到し、最終的に808人が被害を受け、不正利用された金額は約3,861万円にのぼりました。そして同年9月30日、サービスはわずか3ヶ月で完全終了しました。
「認証の不備」という言葉ではまとめられていますが、実際に何が起きたのか、そしてなぜこれがAI開発とも無縁ではないのかを、具体的に掘り下げます。
何が起きたのか:3つの致命的な欠陥
1. パスワードリセットが生年月日で突破できた
7payのパスワードリセット機能には、重大な設計ミスがありました。「生年月日」と「登録メールアドレス」を入力すると、パスワードリセット用のリンクを別のメールアドレスに送信できる仕様になっていたのです。
つまり攻撃者は、氏名・生年月日・メールアドレスさえ知っていれば(あるいは推測できれば)、被害者に気づかれることなくパスワードをリセットし、アカウントを乗っ取れました。生年月日は多くのSNSに公開されている情報です。これはパスワードリセットの設計として根本的に間違っていました。
2. リスト型攻撃への無防備
「リスト型攻撃(クレデンシャルスタッフィング)」とは、他サービスから流出したIDとパスワードのリストを使って、別のサービスに自動ログインを試みる攻撃手法です。多くのユーザーが複数サービスで同じパスワードを使い回しているため、成功率が驚くほど高い。
7payにはログイン失敗回数の制限がなく、ボットによる大量試行を防ぐ仕組みがありませんでした。1アカウントに対して何千回でもログイン試行できる状態だったということです。
3. 2要素認証が存在しなかった
現代のフィンテックサービスとして、2要素認証(2FA)は最低限の要件です。しかし7payにはそれがありませんでした。パスワードさえ合えばログインできてしまう。決済機能を持つサービスとして、これは致命的でした。
なぜ「大企業」がこのミスを犯したのか
セブン-イレブンは日本最大級の小売チェーンです。開発にはそれなりの予算と人員が投入されていたはずです。それでもこの事件が起きた背景には、「リリース優先」のプレッシャーと、セキュリティレビューの軽視がありました。
記者会見でのCOOの「2段階認証は知らなかった」という発言は象徴的です。開発チームがセキュリティの専門家に適切な確認をしないまま、リリースを強行した可能性が高い。
AI開発との危険な共通点
ここからが本題です。AIに「ログイン機能を実装して」と指示すると、確かに動くコードが返ってきます。メールアドレスとパスワードで認証し、セッションを発行し、ログアウトができる。「ログイン機能」として一見完成しているように見えます。
しかし、AIが生成するコードには、セキュリティ上の細かい考慮が抜けることが多い。なぜかというと、AIはあなたの質問に答えようとするだけであって、「あなたが聞いていないこと」は積極的に教えてくれないからです。
AIが見落としやすい認証の5つの落とし穴
1. パスワードリセットURLの有効期限
AIが生成するパスワードリセット機能は、多くの場合トークンを生成してメールで送るところまでは実装されています。しかしそのトークンに有効期限が設定されていないケースがあります。有効期限がなければ、攻撃者は古いリセットリンクを使っていつでもアカウントを乗っ取れます。リセットURLの有効期限は15〜60分程度が適切です。
2. メールアドレス変更時の旧アドレスへの通知
ユーザーがメールアドレスを変更した際、新しいアドレスへの確認メールだけでなく、旧アドレスへの「変更通知メール」も必要です。これがないと、アカウントを乗っ取った攻撃者が静かにメールアドレスを変更しても、本人が気づく手段がありません。
3. ログイン失敗回数の制限
同一IPまたは同一アカウントへのログイン失敗が一定回数(たとえば10回)を超えたら、一時的にロックするか、CAPTCHA認証を要求する。これがないとブルートフォース攻撃やリスト型攻撃がやり放題です。AIが生成するデフォルトのログインコードには、この制限が含まれていないことが多い。
4. セッション固定攻撃への対策
ログイン成功時に、セッションIDを必ず再生成する必要があります。ログイン前後で同じセッションIDを使い回すと、攻撃者が事前に仕込んだセッションIDを乗っ取れる(セッション固定攻撃)リスクがあります。NextAuth.jsやClerkを使えばこれは自動で処理されますが、自作の認証コードでは見落としがちです。
5. 2要素認証(2FA)の欠如
決済機能、個人情報、課金情報を扱うサービスには2FAは必須です。AIに「2FAも実装して」と明示的に指示しないかぎり、生成されるコードにはこれが含まれません。
2025年のMVPにおける認証の最低ライン
個人開発のMVPであっても、本番環境でユーザーデータを扱う以上、以下は省略できません。
- メールアドレス確認(確認リンクをクリックしないと使えない)
- パスワードの強度チェックと安全なハッシュ化(bcrypt以上)
- ログイン失敗回数の制限
- パスワードリセットURLの有効期限設定
- ログイン後のセッションID再生成
- HTTPSの強制
これを自前で正確に実装しようとすると、数日〜1週間の工数がかかります。そして「なんとなく動く」と「セキュアに動く」は全く別物です。
Clerkを使えばほぼ全部カバーできる
個人開発者にとって最も現実的な選択肢は、Clerkのような認証専用SaaSを使うことです。ClerkはSMS/メールによるOTP認証、Google・GitHubなどのOAuth、マジックリンク、パスワードログイン、MFA(多要素認証)をすべてデフォルトで提供しています。
実装コードは驚くほど少なく済みます。
// middleware.ts にこれだけ書けば全ページに認証をかけられる
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
const isPublicRoute = createRouteMatcher(["/", "/sign-in(.*)", "/sign-up(.*)"]);
export default clerkMiddleware(async (auth, request) => {
if (!isPublicRoute(request)) {
await auth.protect();
}
});
無料プランで月間10,000アクティブユーザーまで対応できます。「認証だけで3日かかった」という時間を、コア機能の開発に使いましょう。
コストの比較:正しくやる vs やり直す
認証のセキュリティ対策を最初から正しく実装するコスト(Clerkなら実質ゼロ)と、事故が起きてから対応するコストは比べ物になりません。
7payの場合、サービス終了に伴う損失は被害額の3,861万円だけでなく、開発・運用コスト、ブランドへのダメージ、法的対応コスト、ユーザーへの補償など、総合的には数億円規模の損失と推定されます。個人開発であっても、認証事故は「サービスの終了」に直結します。
認証は「あとで直せる」機能ではありません。最初から正しい選択をするコストは、ほぼゼロです。
→ AI生成コードに潜むセキュリティリスクの全体像はAI生成コードのセキュリティリスク10選を参照
→ 非エンジニアが最低限やるべき対策はVibe Codingで最低限やるべきセキュリティ対策にまとめている