A $3,500-Worth HTML Injection by Abusing CSRF-like

Chaining a Low-Severity HTML Injection with Same-Site Request Forgery to Escalate Impact.

Featured image

In mid Q3 of 2025, my partner (@fariqfgi) and I decided to jump back into bug bounty after a long hiatus. Unfortunately, things didn’t go as planned, two full weeks went by with nothing but frustration and zero findings.

In the middle of that chaos, my partner discovered an HTML Injection issue. However, he wasn’t confident enough to report it (worried it would end up being marked as Not Applicable).

That’s when I spent the next two days thinking hard: “Is there a way to actually get paid from a seemingly low-impact bug like this?.”

Lack of Token-based CSRF Protection

After giving it some serious thought, I started closely observing the application’s behavior. That’s when I noticed that there was no token-based CSRF protection in place.

I quickly realized something important.

Relying on the SameSite attribute does not fully mitigate Request Forgery vulnerabilities.

Why?

The SameSite attribute primarily works by restricting cookies from being sent along with cross-site requests.

cross-site blocked

But things get interesting when the attack scenario shifts like this.

same-site accepted

I know this is a bit of an edge case. But, with no token-based CSRF protection, an HTML Injection vulnerability makes it highly possible to perform sensitive actions.

Form Injection to Request Forgery

Alright, now let’s talk about how we crafted the payload.

First, we looked for a feature or endpoint with the highest potential impact (such as deleting data or updating data).

In our case, since the target application had a feature for adding new users to the organization, we abused this functionality to achieve Account Takeover by creating a new user.

So, the payload we crafted roughly followed this structure:

Sample HTML Injection Payload

<form action="/manage/users" method="POST">
<input type="hidden" name="username" value="xchopath@wearehackerone.com">
<input type="hidden" name="role" value="admin">
<button>Submit</button>
</form>

After the HTML Injection payload was submitted, I asked the admin (my partner as the organization owner) to submit the form and this was the result.

account created

After we successfully pulled off the PoC, we wasted no time reporting the finding. And the moment of truth…

account created

Summary