個人開発で「他人のプロフィールが丸見え」事故を起こした話:MVPでも最低限やるべきAPI認証設計

当ページのリンクには広告が含まれています。
IT女子 アラ美
🚀 セキュリティ事故を起こす前にスキルを上げなさい!
セキュリティ設計ができるエンジニアの市場価値は年々上がっているわよ
自分らしく働けるエンジニア転職を目指すなら【strategy career】
この記事の結論
個人開発サービスのMVPリリース直後に、全ユーザーのプロフィールが誰でも閲覧・編集できる状態だったことが発覚しました。「認証は後で」は許されても、「他人のデータにアクセスできる設計」は絶対にダメです。本記事では事故の全容と修正手順、MVPでも最初からやるべきセキュリティ対策を共有します。

お疲れ様です!IT業界で働くアライグマです!

「MVPだからセキュリティは後で」「まずは動くものを出すのが最優先」。個人開発でこう判断した経験、ありませんか?

実は先日、自分が開発した技術記事キュレーションサービス「DevPick」で、まさにこの判断が致命的なセキュリティ事故を引き起こしました。この記事では、何が起きて、なぜ起きて、どう修正したかを包み隠さず共有します。

目次

個人開発サービスでセキュリティ事故が起きた背景

IT女子 アラ美
💡 セキュリティの基礎を独学で済ませてない?
Webアプリの認証設計を体系的に学べる個人レッスンで実力を証明しなさい
資格と仕事に強い!個人レッスンのプログラミングスクール【Winスクール】

DevPickは、Zenn・Qiita・Hacker Newsなど10ソースからAIが技術記事をスコアリングし、ユーザーの興味に合った記事だけを毎日届けるサービスです。バックエンドはFastAPI + MySQL、フロントエンドはNext.jsで構成しています。

ユーザーがプロフィール(名前・職種・習熟度・興味ジャンル)を登録すると、AIがそれに基づいて記事のスコアリングを行います。つまり、プロフィール情報はサービスの根幹であり、本来は厳重に保護すべきデータでした。

しかし、MVPリリースの際に「認証は後で入れる。まずは動くものを出す」と判断しました。これが事故の始まりです。AI活用サービスの開発についてはGAS×Claude APIでSlack自動投稿する方法でも触れていますが、機能開発に集中するあまりセキュリティが後回しになるのは個人開発あるあるです。

IT女子 アラ美
「認証は後で」って、個人開発やったことある人なら一度は言ったことあるよね…。私も身に覚えがある。

ITアライグマ
正直、自分も「まず動くものを出す」を優先しすぎました。反省しています。

何が起きたか:全ユーザーのプロフィールが丸見え

リリース直後、致命的な問題が2つ見つかりました。

問題1:ユーザー一覧APIが丸見え

GET /api/users/ を叩くと、登録済みの全ユーザーのプロフィールがリストで返ってくる状態でした。

[
  {"id": 1, "name": "あらいぐま", "role": "backend_engineer", ...},
  {"id": 2, "name": "YSK", "role": "fullstack_engineer", ...}
]

認証なし、レート制限なし。誰でもアクセス可能でした。

問題2:IDを推測すれば他人のプロフィールを操作できる

GET /api/users/2 で他人のプロフィール詳細が取得できるだけでなく、PUT /api/users/2他人のプロフィールを書き換えることすらできました。

フィード、いいね、既読もすべて user_id をクエリパラメータで渡すだけで、本人確認は一切なし。LLMアプリケーションのセキュリティについてはOWASP Top 10ガードレールガイドでも解説していますが、APIの認証不備はOWASP Top 10の1位に挙げられる最も基本的な脆弱性です。

IT女子 アラ美
PUT /api/users/2 で他人のプロフィール書き換えられるって…。想像しただけでゾッとする。

ITアライグマ
curlで1行打つだけで書き換えられる状態でした。ブラウザからは見えないから気づきにくいのが怖いですね。

なぜ起きたか:「MVPだから後で」の罠

認証なし ≠ アクセス制御なし

最初の設計で「MVPでは認証を入れない」と決めました。理由は「早くリリースしたいから」。

これ自体は個人開発ではよくある判断です。しかし、認証を入れないことと、他人の情報が見えることは別の問題です。認証がなくても、最低限以下は必要でした。

  • ユーザー一覧APIを作らない(または削除する)
  • プロフィール作成時にトークンを発行し、以降の操作でトークンを要求する

使わなくなったAPIが残っていた

開発初期に「マルチユーザー切り替え」機能を作り、ドロップダウンでユーザーを選択するために一覧取得APIを実装しました。その後、MVP向けにマルチユーザー機能を削除したのですが、APIだけ消し忘れた。フロントエンドからは呼ばなくなったので気づかず、そのまま本番に出してしまいました。

脆弱性の自動検出についてはセキュリティテスト実践ガイドで解説していますが、使われなくなったエンドポイントの検出もテストに含めるべきでした。

IT女子 アラ美
フロントから呼ばなくなったAPIって、存在を忘れるよね。でもAPIは直接叩けるんだから…。

ITアライグマ
「ブラウザで見えないから安全」は完全な幻想です。curlが使える人なら誰でもアクセスできますからね。

どう修正したか:3ステップの緊急対応

Step 1:ユーザー一覧APIの即時削除

最も危険な一覧APIを即座に削除しました。

# 削除: @router.get("/", response_model=list[UserProfileResponse])
# この API は存在してはいけなかった

Step 2:トークン認証の導入

プロフィール作成時にランダムなトークンを発行し、以降のAPI操作では X-DevPick-Token ヘッダーでの認証を必須にしました。

@router.post("/", status_code=201)
def create_user_profile(payload: UserProfileCreate, db):
    profile = UserProfile(
        token=secrets.token_hex(32),
        name=payload.name,
        role=payload.role,
    )

取得・更新・削除にはトークンが必須です。secrets.compare_digest でタイミング攻撃を防止しています。

@router.get("/{user_id}")
def get_user_profile(user_id, x_devpick_token: str = Header(...), db):
    profile = db.query(UserProfile).filter(UserProfile.id == user_id).first()
    if not secrets.compare_digest(profile.token, x_devpick_token):
        raise HTTPException(status_code=403, detail="Invalid token")
    return profile

Step 3:DBマイグレーション

本番のMySQLに token カラムを追加し、既存ユーザーにもトークンを発行しました。FastAPIの本番運用についてはFastAPI本番運用ガイドでも解説しています。

ALTER TABLE user_profiles ADD COLUMN token VARCHAR(64);
UPDATE user_profiles SET token = MD5(RAND()) WHERE token IS NULL;
ALTER TABLE user_profiles MODIFY token VARCHAR(64) NOT NULL;
CREATE UNIQUE INDEX ix_user_profiles_token ON user_profiles(token);

IT女子 アラ美
タイミング攻撃防止まで入れてるの偉い。事故った後だからこそ丁寧になるよね。

ITアライグマ
痛い目を見た後の対応は自然と慎重になります。最初からこのレベルでやるべきでしたね。

ケーススタディ:修正前後のセキュリティ比較

IT女子 アラ美
💡 セキュリティ設計を主導できる環境で働きなさい!
社内SEなら自社アプリのセキュリティ設計を一から手がけられるわよ
社内SEを目指す方必見!IT・Webエンジニアの転職なら【社内SE転職ナビ】

ここでは、山田さん(仮名・29歳・バックエンドエンジニア・経験4年)が個人開発サービスで遭遇したセキュリティ事故の修正前後を数値で比較します。

状況(Before)

  • 脆弱なエンドポイント数:8箇所(全APIが認証なし)
  • 外部アクセス可能なユーザーデータ:全件(名前、職種、興味ジャンル)
  • 他人のデータを変更可能か:はい(PUT /api/users/{id} で書き換え可能)
  • 心境:「リリースできた嬉しさで、セキュリティのことを完全に忘れていた」

行動(Action)

  • 不要APIの削除:ユーザー一覧APIを即座に削除(作業時間5分)
  • トークン認証の実装:全APIエンドポイントにトークン認証を追加(作業時間3時間)
  • DBマイグレーション:既存ユーザーへのトークン発行+スキーマ変更(作業時間30分)
  • curlでの全エンドポイントテスト:認証なしでアクセスできないことを全件確認(作業時間15分)

結果(After)

  • 脆弱なエンドポイント数:8箇所 → 0箇所
  • 外部アクセス可能なユーザーデータ:全件 → 0件(トークンなしではアクセス不可)
  • 修正にかかった総工数約4時間(最初から入れていれば1時間で済んだ)

振り返ると、「不要APIの削除とトークン認証は、MVPでも初日から入れるべきだった。4時間の作業を後回しにしたことで、リリース後の冷や汗を味わうことになった」。入力値の検証もセキュリティの重要な一環です。Pydantic v2の実装パターンも参考にしてください。

IT女子 アラ美
最初から入れていれば1時間で済んだのに、後からだと4時間。しかも冷や汗付き。割に合わないね。

ITアライグマ
「技術的負債の利息」と同じ構造です。後回しにするほどコストが膨らみます。

MVPでも最初からやるべきセキュリティ対策チェックリスト

この事故から得た教訓を、チェックリスト形式でまとめます。

リリース前に確認すべき3つのポイント

  • 不要なAPIエンドポイントが残っていないか:開発中に作ったが本番では使わないAPIは全て削除する。フロントから呼ばないAPIも、直接叩けば動く
  • 他人のデータにアクセスできない設計になっているか:認証を入れなくても、トークンやセッションで「自分のデータだけ操作できる」仕組みは入れられる
  • curlで全エンドポイントを叩いたか:ブラウザの画面テストだけでは不十分。5分で終わる作業が、信頼の損失を防ぐ

認証を入れない場合の最低限の設計

  • プロフィール作成時にランダムトークンを発行し、localStorageに保存
  • 以降のAPI操作ではトークンをヘッダーに付与
  • ユーザー一覧APIは作らない(管理画面用にどうしても必要なら、別のパスに分離してBasic認証をかける)

セキュリティ設計のスキルは転職市場でも高く評価されます。社内SE転職エージェント3社比較で紹介しているような社内SEポジションでは、自社アプリのセキュリティ設計を主導する裁量を持てます。

IT女子 アラ美
チェックリスト、次のリリースから使わせてもらうわ。curl全エンドポイントテスト、5分で終わるなら絶対やるべき。

ITアライグマ
「5分の投資で信頼を守る」と考えると、やらない理由がないですよね。ぜひ習慣にしてください。

よくある質問

MVPでOAuth2やJWTを実装すべきですか?

MVPの段階ではオーバーキルになることが多いです。まずはランダムトークン + ヘッダー認証で十分です。ユーザー数が増えてきたら、OAuth2やJWTへの移行を検討しましょう。

localStorageにトークンを保存して安全ですか?

XSS攻撃のリスクはありますが、個人開発のMVPレベルでは現実的な選択肢です。本格運用する場合はHttpOnly Cookieへの移行を推奨します。CSRFトークンとの組み合わせも検討してください。

この事故でユーザーに被害はありましたか?

幸い、リリース直後に気づいて即座に修正したため、実被害は確認されていません。ただし「被害がなかった」のは運が良かっただけで、対策が不十分だった事実は変わりません。

本記事で解説したようなAI技術を、基礎から体系的に身につけたい方は、以下のスクールも検討してみてください。

比較項目 Winスクール Aidemy Premium
目的・ゴール 資格取得・スキルアップ初心者〜社会人向け エンジニア転身・E資格Python/AI開発
難易度 初心者◎個人レッスン形式 中級者〜コード記述あり
補助金・給付金 最大70%還元教育訓練給付金対象 最大70%還元教育訓練給付金対象
おすすめ度 S幅広くITスキルを学ぶなら AAIエンジニアになるなら
公式サイト 詳細を見る
IT女子 アラ美
AIスキルを身につけたいけど、どのスクールを選べばいいかわからないです…
ITアライグマ
現場で即・ITスキルを身につけたいならWinスクールがおすすめです!個人レッスン形式で初心者でも取り組みやすいですよ。

まとめ

個人開発のMVPだからといって、セキュリティを後回しにしてはいけません。

  • 認証なし ≠ アクセス制御なし。認証を入れなくても、他人のデータにアクセスできない設計は必須
  • 使わなくなったAPIは必ず削除。フロントから呼ばなくなったエンドポイントも直接叩ける
  • リリース前にcurlで全エンドポイントを叩け。5分で終わる作業が信頼の損失を防ぐ
  • 最初から入れていれば1時間で済む対策を後回しにすると、4時間の修正工数と冷や汗がかかる

DevPickは現在トークン認証を導入済みです。興味があればぜひ使ってみてください。

IT女子 アラ美
個人開発で同じ失敗をする前にこの記事に出会えてよかった。curlテスト、今日からやるわ。

ITアライグマ
5分のcurlテストが最大の防御線です。ぜひ習慣にしてください。

厳しめIT女子 アラ美による解説ショート動画はこちら

作者が開発したサービス「DevPick」

この記事をシェアする
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

ITアライグマのアバター ITアライグマ ITエンジニア / PM

都内で働くPM兼Webエンジニア(既婚・子持ち)です。
AIで作業時間を削って実務をラクにしつつ、市場価値を高めて「高年収・自由な働き方」を手に入れるキャリア戦略を発信しています。

目次