When data crosses into a system that interprets structure, without being constrained or transformed, it becomes executable.
User input is embedded in output markup and executed by the rendering engine (browser, template)
If user input appears inside a query, command, template, object stream, or prompt without an intermediate representation that separates data from structure — you are not passing data. You are modifying structure.
Every new execution context recreates this pattern. SQL gave way to NoSQL, HTML to templates, cookies to JWTs, forms to APIs, prompts to agents. The language changes. The failure does not.
Same boundary collapse — SQL targets the database layer, XSS targets the presentation layer
XSS injects script into HTML rendering. Prompt injection injects instructions into LLM reasoning. Same boundary collapse, new execution context
XSS can deliver CSRF attacks — boundary collapse in the browser enables ambient authority exploitation
Year
1999–present
Context
Websites became interactive. User-generated content — comments, profiles, search queries — was displayed back to other users. The server took user input, embedded it in HTML, and sent it to the browser. The browser couldn't distinguish between the page's legitimate JavaScript and JavaScript injected through user input. If the input contained , the browser executed it. Every user who viewed the page ran the attacker's code.
Who Built This
Web developers building forums, guestbooks, search pages, and any feature that reflects or stores user input. The server-side languages — PHP, ASP, JSP — made it trivially easy to echo user input into HTML. The tutorials showed echo $_GET['search'] without mentioning the consequences.
Threat Model at Time
Server-side attacks. SQL injection. Defacement. Nobody modeled the browser as an attack surface because JavaScript was considered a toy language for form validation and rollover effects.
Why It Made Sense
Echoing user input into HTML was how dynamic pages worked. Search results showed "You searched for: X." Profile pages showed the user's bio. Comment threads displayed what people typed. The input was displayed because displaying it was the feature.
This pattern has been found in applications built by talented developers at respected organizations across every decade of software history. Its presence in a codebase is not a reflection of the developer who wrote it — it is a reflection of what that developer was taught, what tools they had, and the path that was easiest given what they were taught. The goal is not to find fault. The goal is to find the pattern — before it finds you.
Katie's Law: The developers were not wrong. The shortcut was not wrong. The context changed and the shortcut didn't.