Today I didn't do a lot because I was feeling a bit low, but still, I managed to learn something.

Last time, I covered the basics of CSRF and solved a lab to understand it practically. But that lab didn't include any kind of CSRF protection or defense.

Understanding CSRF Tokens

According to PortSwigger, the next step is to learn about CSRF defenses and how to bypass them.

The first defense is CSRF tokens.

A CSRF token is a unique, secret, and unpredictable value generated by the server and shared with the client. When a user performs a sensitive action (like changing email or updating profile details), the request must include the correct token.

This makes it difficult for an attacker to forge a valid request.

A common implementation looks like this:

<form name="change-email-form" action="/my-account/change-email" method="POST">
    <label>Email</label>
    <input required type="email" name="email" value="example@normal-website.com">
    <input required type="hidden" name="csrf" value="50FaWgdOhi9M9wyna8taR1k3ODOR8d6u">
    <button class='button' type='submit'>Update email</button>
</form>

This generates a request like:

POST /my-account/change-email HTTP/1.1
Host: normal-website.com
Content-Type: application/x-www-form-urlencoded
csrf=50FaWgdOhi9M9wyna8taR1k3ODOR8d6u&email=example@normal-website.com

I also found an important note:

CSRF tokens don't always have to be in POST requests. Some applications include them in headers. The way tokens are handled directly impacts security.

Lab Insight

Before starting the lab, PortSwigger explained something interesting:

Some applications validate CSRF tokens correctly for POST requests, but skip validation for GET requests.

That's where the vulnerability comes in.

My Approach

I started the lab and logged in using the provided credentials.

None

Then:

  • Changed the email
  • Captured the request using Burp Suite
  • Analyzed how the functionality works

Next:

  • Sent the POST request to Repeater
  • Removed unnecessary headers
  • Verified that the request still works

The Key Step

Here's the important part:

None
None

I changed the request method from POST → GET

Then I moved the parameters into the URL like this:

/my-account/change-email?email=test@example.com&csrf=TOKEN

And surprisingly… it still worked.

That means: The server was not validating CSRF token properly for GET requests

Exploitation

Now I needed to create a CSRF exploit.

None
  • I copied the modified request
  • Generated an HTML PoC
  • Pasted it into the exploit server

Then I added this script to auto-submit the request:

None
<script>document.forms[0].submit();</script>

So now:

  • The request triggers automatically
  • No user interaction is needed

Finally:

  • Stored the exploit
  • Delivered it to the victim

Lab solved

What I Learned

  • CSRF tokens are strong, but only if implemented correctly
  • Validation must be consistent across all HTTP methods
  • Even small logic flaws (like skipping validation on GET) can break security

After finishing this, I worked a bit on my college project — I'm building a subdomain finder tool.

If you guys want, I can share more about it in future posts.

Alright, I'll see you in the next story. Till then, keep learning new things