Stored Cross-Site Scripting (Stored XSS) in the Testimonials / Community Feed functionality.
During testing of the “Leave a Testimonial” feature, user-controlled input was improperly sanitized before being rendered inside the Community Feed component.
This allowed arbitrary HTML injection and JavaScript execution through crafted payloads.
The vulnerability was exploitable with a single interaction and worked in the latest version of Google Chrome, satisfying the challenge requirements.
- Testimonials submission form
- Community Feed renderer
Potential vulnerable sink:
element.innerHTML = userInput;The application failed to properly sanitize user-controlled input before inserting it into the DOM.
The payload abuses HTML parsing behavior by breaking out of an attribute context and injecting a malicious <img> tag with an onerror event handler.
<title><img title="</title><img src onerror=alert(document.domain)>"></title>-
Navigate to:
https://challenge-0526.intigriti.io/challenge -
Login or create an account.
-
Open the Testimonials section.
-
Submit the following payload as a testimonial:
<title><img title="</title><img src onerror=alert(document.domain)>"></title>-
Refresh or revisit the Community Feed.
-
The payload executes automatically:
alert(document.domain)The payload works because:
- The application reflects or stores user input inside an HTML context.
- The browser interprets the malformed
<title>structure and repairs the DOM. - The injected
<img>element triggers anonerrorevent because thesrcattribute is invalid/missing. - JavaScript executes within the victim’s browser context.
The effective injected node becomes:
<img src onerror=alert(document.domain)>Successful exploitation allows attackers to:
- Execute arbitrary JavaScript
- Steal session tokens
- Perform authenticated actions
- Deface application content
- Phish users
- Exfiltrate sensitive information
Because the payload is stored, every user viewing the malicious testimonial becomes a potential victim.
Attached mp4 demonstrating exploitation flow:
- Login
- Payload injection
- Stored execution inside Community Feed
0526.mp4
Do not use:
innerHTMLUse safer alternatives:
textContent
innerText
createTextNode()Use a well-maintained sanitizer such as:
- DOMPurify
Example:
DOMPurify.sanitize(userInput)Apply proper escaping depending on context:
- HTML
- Attributes
- JavaScript
- URLs
Implement a strict Content Security Policy:
Content-Security-Policy:
default-src 'self';
script-src 'self';
object-src 'none';
base-uri 'none';This challenge highlights several important offensive and defensive concepts:
- HTML parser abuse is still extremely effective.
- Attribute/context breaking remains common in modern web apps.
- Retro-themed frontends often hide intentionally vulnerable rendering logic.
- Stored XSS is significantly more dangerous than reflected XSS because it scales to every viewer.
A small rendering mistake can fully compromise all authenticated users.
<title><img title="</title><img src onerror=alert(document.domain)>"></title>- Vulnerability discovered during testimonial rendering analysis
- Confirmed stored execution in Community Feed
- Verified in latest Chrome
- Write-up completed for disclosure