The Sleeper Agent Bug: How One HTML Payload Lay Hidden for Months to Attack My Inbox ⏳
Press enter or click to view image in full sizeA short recon story about a delayed HTML injection, a 2026-5-19 09:0:53 Author: infosecwriteups.com(查看原文) 阅读量:21 收藏

LordofHeaven

Press enter or click to view image in full size

A short recon story about a delayed HTML injection, a surprising phishing vector, and why every output channel deserves the same hardening as your web UI.

When I first started poking around a site I’d signed up for long ago — let’s call it xyz.com — I was in bug-hunting mode. I threw common payloads into every visible input field, especially the Name field, because that’s one of the easiest places developers forget to sanitize properly.

My test payload was intentionally multi-purpose: a tiny template expression, an HTML anchor, and an input element — designed to probe different rendering contexts at once.

{{8*8}}/”><A HREF=evil.com>HELLO</A”>
{{8*8}}"><A HREF="http://evil.com">HELLO</A>

I hit Save, checked my profile page, and… nothing useful. The UI showed the name as raw/encoded text — no math evaluated, no clickable link, no input element. I logged it as negative and moved on. The payload became a ghost, quietly stored in xyz.com’s database.

The Return of the Phantom 👻

Months later, while skimming my inbox, I saw an email from xyz.com: “Checking your security settings.” At first glance it seemed legit — corporate copy, brand styling, the whole nine yards. Then I froze.

Right above the sign-off, where my name should have been dynamically inserted, the exact payload I’d submitted months earlier had been rendered — HTML and all. The template expressions had been evaluated to numbers. The <a> tag had become a clickable link to http://evil.com. Even an actual HTML input field appeared inside the email.

Get LordofHeaven’s stories in your inbox

Join Medium for free to get updates from this writer.

Remember me for faster sign in

Seeing your own test payload show up, fully alive, in an official email from a trusted service is a mix of validation and dread. Validation because your test worked; dread because an attacker could weaponize the same oversight against many users.

Press enter or click to view image in full size

What happened (simple breakdown)

  1. I submitted a value containing HTML into the Name field.
  2. xyz.com stored that value in its database.
  3. The web UI escaped or encoded the value (so it looked safe in-browser).
  4. Later, an email template interpolated the stored value into an HTML email without proper escaping.
  5. The mail client rendered the injected HTML, producing a live link and form control — exactly what I injected.

Short version: stored unescaped input → inserted into HTML email → rendered by mail client = stored HTML injection in email.

Why this is dangerous

  • Users trust official emails. People are far likelier to click a link from a service they use than from a random site.
  • Email clients don’t enforce browser CSPs. Many protections that exist in browsers are absent or weaker in mail clients.
  • Wide blast radius. If that template is used for security emails or mass notifications, many users could be exposed.
  • Social engineering potential. Attackers can craft plausible phishing content with vendor branding and context.

Quick developer checklist — fixes that actually help

  • Escape user input when rendering HTML emails. Encode <, >, &, ", ' (&lt;, &gt;, &amp;, &quot;, &#x27;).
  • Use auto-escaping provided by your template engine; avoid marking user data safe/raw.
  • Whitelist characters for name-like fields (letters, digits, spaces, common punctuation).
  • Prefer plain-text for critical security emails (password resets, MFA changes).
  • Normalize input at ingestion as a second line of defense.
  • Test templates with malicious payloads in CI to catch regressions.
  • Audit all output sinks: web UI, emails, admin panels, logs, PDFs, mobile push — anything that can render user data.

Final thoughts

A tiny, forgotten field can become a powerful attack vector when stored and later reused in a different context. Don’t assume “no visible reflection in the UI = safe.” Treat every output channel as hostile, and apply the same rigorous escaping and testing you use for front-end XSS across email templates and other async outputs.


文章来源: https://infosecwriteups.com/the-sleeper-agent-bug-how-one-html-payload-lay-hidden-for-months-to-attack-my-inbox-9d3f1e9df60e?source=rss----7b722bfd1b8d--bug_bounty
如有侵权请联系:admin#unsafe.sh