June 2, 2026
My Account take Over bug
In this writeup, I will walk you through my very first bug discovery: a critical Account Takeover (ATO) vulnerability in a major management…
Hatim Lahwaouir
2 min read
In this writeup, I will walk you through my very first bug discovery: a critical Account Takeover (ATO) vulnerability in a major management company. I spent two weeks thoroughly mapping out the application, understanding its authentication flows, features, and underlying business logic.
Phase 1: Analyzing Session Management
While reviewing the authentication mechanism, I noticed the application stored user sessions in localStorage. This meant standard state-changing CSRF was mitigated, but any Cross-Site Scripting (XSS) vulnerability could easily lead to an ATO. However, after an additional week of testing, I couldn't find any direct XSS entry points.
Instead, I focused on an interesting feature: Change Region. This allowed users to migrate where their management team data was hosted (e.g., moving data from the US to Africa).
When changing regions, the subdomain changed from us.example.com to af.example.com. What caught my attention was that I remained seamlessly logged in. Since localStorage adheres strictly to the Same-Origin Policy (SOP) and cannot be shared across different subdomains, I investigated how they were passing the session.
I discovered that the application used JavaScript to set a session cookie scoped to the wildcard domain: .example.com.
The Cookie Sharing Flow:
us.example.comsets a session cookie scoped to.example.com.- The browser redirects to
af.example.com. af.example.comautomatically reads the wildcard cookie, keeping the user authenticated.
The Security Flaw:
- The cookie lacked the
HttpOnlyflag. - The cookie domain was overly broad (
.example.com), meaning any subdomain underexample.comcould read it via JavaScript.
Phase 2: Finding the XSS Entry Point
I continued my reconnaissance and found an ad-creation feature. The platform allowed users to design custom advertisements using HTML/JS templates. When a user previewed their template, the app generated a preview URL hosted on a separate subdomain: edit.example.com.
Because the platform allowed custom JavaScript execution within the preview, I successfully achieved Stored XSS on edit.example.com. Since the session cookie from the main app was scoped to .example.com and lacked HttpOnly, my XSS payload could easily read it via document.cookie.
However, there was a catch: to view the preview link on edit.example.com, the viewer had to be authenticated. I couldn't simply send my preview link to a random victim because they wouldn't have permission to view my private ad template.
Phase 3: The Missing Link — Login CSRF
To bypass the authentication restriction on the preview page, I looked into the platform's OAuth implementation. I discovered a Login CSRF vulnerability due to a complete lack of validation on the state parameter.
This allowed me to forge an authentication request that would force a victim's browser to log into my attacker account.
The Final Attack Chain (Exploit Scenario)
By chaining Login CSRF, Overly Broad Cookie Scoping, and Stored XSS, the final exploit works as follows:
- The Hook: The attacker sends a malicious link to the victim.
- Login CSRF: Clicking the link triggers the OAuth flaw, silently logging the victim into the attacker's account.
- XSS Execution: The victim's browser is then automatically redirected to the malicious ad preview on
edit.example.com(which they can now view because they are logged into the attacker's account). - Session Theft: Trigger the change region feature then the stored XSS payload executes. Because the session cookies are scoped to
.example.comwithoutHttpOnly, the JavaScript extracts the cookie data and exfiltrates it to the attacker's request catcher. - Account Takeover: The attacker uses the exfiltrated session token to gain full control of the account.
Since this is my first technical writeup, I would love to hear your feedback! If you spot any technical errors, typos, or areas where the logic could be clearer, please let me know in the comments or reach out to me directly