July 12, 2026
XSS as a Password Stealer — A very overlooked XSS attack vector
Hi everyone, it’s been a while since my last article in 2022: A Deep dive into <iframe> src=”” attribute leading to a Stored XSS. I have…

By Abdulah AlSolaiman
4 min read
Hi everyone, it's been a while since my last article in 2022: A Deep dive into . I have been busy, very.
well, this time I come to you with an article after what? 4 years? not to mention that this article idea came in 2022, so I am posting it 4 years later but I still think it is a valid research, and as you know me, I don't post just another AI-crap or LinkedIn certified cringe, so I hope you find this useful. (p.s now I remembered the Sadio Mané Liverpool fan meme):
And here I come to you with an absolute. Enough it enough, I won't wait for the perfect time or perfect article, I will just write.
What is it about?
Well, to start with, my article is simple. It's a MASSIVELY overlooked Cross-Site Scripting technique that allows you to exfiltrate victim's password. Yep,your heard it right. XSS to Password Stealer in no effort. And it's not some new invention, it's been there forever, people did research on it, but the community didn't give it much attention, so now, I am bringing it back, rising from the darkness of all cybersecurity world.
Story Time — Thought Process of discovery
Well, it's story time and I love telling stories. Back in the day, 2022, I was penetration testing for one of the clients, let's call him X-Corp. The web application had a login page which is typical.. bare with me. It had a login page, and guess that the login form html looked like? A typical login form.
<form>
<input type="text"
name="ctl00$ctl00$ctl00$ContentPlaceHolder1$UserLogin$txtUserName"
placeholder="Username">
<input type="password"
name="ctl00$ctl00$ctl00$ContentPlaceHolder1$UserLogin$txtPassword"
placeholder="Password">
<input type="submit"
name="ctl00$ctl00$ctl00$ContentPlaceHolder1$UserLogin$btnSubmit"
value="Login">
</form><form>
<input type="text"
name="ctl00$ctl00$ctl00$ContentPlaceHolder1$UserLogin$txtUserName"
placeholder="Username">
<input type="password"
name="ctl00$ctl00$ctl00$ContentPlaceHolder1$UserLogin$txtPassword"
placeholder="Password">
<input type="submit"
name="ctl00$ctl00$ctl00$ContentPlaceHolder1$UserLogin$btnSubmit"
value="Login">
</form>Well, I logged in.
Now the application is big, but what interests me here is that the application had a functionality whereby a user can go upload a document and sign it with typing in his password. This way when you submit the form, the app knows it is YOU who submitted the form. Perfectly fine right? well, here is how the form looked like.
<form method="post">
<input type="hidden" name="__VIEWSTATE" value="..." />
<h3>Sign Document</h3>
<input type="hidden"
name="ctl00$MainContent$DocumentViewer$hfDocumentId"
value="12345" />
<label>Enter your password to sign this document:</label>
<input type="password"
name="ctl00$MainContent$DocumentSigningControl$txtPassword" />
<br><br>
<input type="submit"
name="ctl00$MainContent$DocumentSigningControl$btnSign"
value="Sign Document" />
</form><form method="post">
<input type="hidden" name="__VIEWSTATE" value="..." />
<h3>Sign Document</h3>
<input type="hidden"
name="ctl00$MainContent$DocumentViewer$hfDocumentId"
value="12345" />
<label>Enter your password to sign this document:</label>
<input type="password"
name="ctl00$MainContent$DocumentSigningControl$txtPassword" />
<br><br>
<input type="submit"
name="ctl00$MainContent$DocumentSigningControl$btnSign"
value="Sign Document" />
</form>I told you, bare with me.
Now, when I tried to submit this form empty without any password, I looked at my burp request and I saw:
POST /DocumentCenter/SignDocument.aspx HTTP/1.1
Host: app.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/137.0.0.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Cookie: ASP.NET_SessionId=abc123xyz
Content-Length: 420
__VIEWSTATE=dGhpcyBpcyBqdXN0IGEgZGVtbw%3D%3D&
ctl00%24MainContent%24DocumentViewer%24hfDocumentId=12345&
ctl00%24MainContent%24DocumentSigningControl%24txtPassword=Summer2025!&
ctl00%24MainContent%24DocumentSigningControl%24btnSign=Sign+DocumentPOST /DocumentCenter/SignDocument.aspx HTTP/1.1
Host: app.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/137.0.0.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Cookie: ASP.NET_SessionId=abc123xyz
Content-Length: 420
__VIEWSTATE=dGhpcyBpcyBqdXN0IGEgZGVtbw%3D%3D&
ctl00%24MainContent%24DocumentViewer%24hfDocumentId=12345&
ctl00%24MainContent%24DocumentSigningControl%24txtPassword=Summer2025!&
ctl00%24MainContent%24DocumentSigningControl%24btnSign=Sign+Documentand I was like WHAT DA HAAILLLL, My password in da request:
I started asking why is my password there in the request? Turns out there is this lazy guy, and him knowing that the test credentials he is testing with will be destroyed right after the pentest, he chose to save his password during login, and the browser choose to auto-fill his password in the form:
But Wait a Second, Why the hell my password is auto-filled in a different place? isn't it supposed to be filled in the login form? not inside the app?
and here I know that you didn't read the two HTML snippets I put for you up there. It's okay I will explain them, but you must know that I knew you were not gonna read them:
Both forms had a thing in common:
form 1:
<input type="password"
name="ctl00$ctl00$ctl00$ContentPlaceHolder1$UserLogin$txtPassword"
placeholder="Password"
><input type="password"
name="ctl00$ctl00$ctl00$ContentPlaceHolder1$UserLogin$txtPassword"
placeholder="Password"
>form 2:
<input type="password"
name="ctl00$MainContent$DocumentSigningControl$txtPassword"
placeholder="Password"
><input type="password"
name="ctl00$MainContent$DocumentSigningControl$txtPassword"
placeholder="Password"
>So basically, my browser saw the word "txtPassword" or more precisely the attribute type = "password" and said: Say no more here is the password slapped right on this <input> field's face.
Until here, you guys see nothing particularly dangerous yet, right? WRONG!
Eureka Moment
Again, bare with me, please. While this seems very classic scenario to most people, to me, the breaker, got this crazy idea, crazy EUREKA! moment and said:
So basically, If I managed to get a Cross-Site Scripting, I could basically use JavaScript to access the values of
<input type="password" name="ctl00$MainContent$DocumentSigningControl$txtPassword" />
Indeed I tried, there was another application that talks with this app, through it managed to find an XSS, STORED XSS, and used it to exfiltrate the user password:
const passwordField = document.querySelector(
'[name="ctl00$MainContent$DocumentSigningControl$txtPassword"]'
);
const password = passwordField.value;
console.log(password);const passwordField = document.querySelector(
'[name="ctl00$MainContent$DocumentSigningControl$txtPassword"]'
);
const password = passwordField.value;
console.log(password);And from then on, it's cake. LisaXss or whatever hre name is will send the password right to your collaborator.
Now I will keep the story short because this article is not to say I did the unthinkable. no, I just used my curiosity to perform one of the nicest XSS escalations paths in my opinion, because let's be frank. I have seen most of people working in Cybersecurity using the auto-fill feature, I assume no one will moving from here … However, there is one last thing.
Technical Analysis
Now I thought I can use AI to generate a nice website that will do the technical analysis for me and slap the word AI on this article, and then I said: let me search the internet if anyone found this finding before I did or wrote about it. This technique occurred to me around Q3-Q4 2022, so I searched, and I could find a bunch of article, however, the following is the deepest technical analysis of all the ones I found, it was published around July 2021 (more than a year before I found it), and as I always like to say: I am not gonna re-invent the wheel, this guy did a great work and you guys should read this technically analysis that covers the behavior in different browsers. Here is the article link You should disable autofill in your password manager
Closing Notes
This technique is not unique, it's been there forever. One thing new someone can do is to re-do this technical analysis on all modern browsers to see if in 2026 this attack vector still exists in its current form.
On this note, I am gonna see you guys in the next article, which will not take 2 years, it will take 2 days hopefully :). I have an interesting one on IoT pentesting and binary reverse engineering, till then, take care!~