CWE-79 is cross-site scripting, usually shortened to XSS. The product does not neutralize, or incorrectly neutralizes, user-controllable input before placing it in output that is served as a web page to other users.
Any site that shows data one person supplied to another person is a candidate: comment boxes, search pages, error pages, profile fields, admin dashboards, chat widgets and AI assistants that render model output as HTML.
How it happens
MITRE notes there are many variants, with different names and attack topologies, but they share one fundamental weakness: improper neutralization of dangerous input between the adversary and a victim. The consequence is the same whether the XSS is stored or reflected. The difference is how the payload reaches the server. Stored XSS is saved and served later to other users. Reflected XSS is echoed straight back from the request.
Here is a reflected case in Python with Flask, using string building:
from flask import request
@app.route("/search")
def search():
q = request.args.get("q", "")
# Vulnerable: q goes into HTML unescaped
return "<h1>Results for " + q + "</h1>"
A request where q contains a script tag makes the browser run that script as if the site had sent it. The same mistake in front-end code:
// Vulnerable: treats text as markup
el.innerHTML = userComment;
The fix is to encode for the context the data lands in. In Jinja, use the template engine's autoescaping. In the browser, assign text, not markup:
from markupsafe import escape
@app.route("/search")
def search():
q = request.args.get("q", "")
return "<h1>Results for " + str(escape(q)) + "</h1>"
el.textContent = userComment;
The observed examples in the record show this is not just an old problem:
- CVE-2024-49038: XSS in an AI assistant.
- CVE-2024-54142: a plugin that enables AI features allows input with HTML entities, leading to XSS.
- CVE-2021-25926: a Python library manager did not sufficiently neutralize a user-supplied search term, allowing reflected XSS.
- CVE-2021-25963: a Python-based e-commerce platform did not escape returned content on error pages, allowing reflected XSS.
See CVE-2024-49038, CVE-2024-54142, CVE-2021-25926 and CVE-2021-25963.
What an attacker gains
MITRE lists three groups of impact.
- Session theft and bypass. The most common attack discloses private information stored in user cookies, such as session information. The attacker crafts client-side script that sends it to them.
- Code execution in the victim's context. In some circumstances, combined with other flaws, it may be possible to run arbitrary code on a victim's computer.
- Broad impact. Reading application data, bypassing protections and executing unauthorized commands, with the same consequence whether stored or reflected.
How to find it
MITRE lists two main techniques.
- Automated static analysis. Tools that target XSS use data flow analysis to limit false positives. MITRE notes this is not perfect, because 100 percent accuracy and coverage are not feasible, especially when several components are involved.
- Black box testing. Use the XSS Cheat Sheet or automated test generation tools to launch a wide variety of attacks, including subtle variants aimed at weak defenses. With stored XSS the indirection between input and output makes this harder, so check each place stored data is displayed.
Click through it at your own pace, or open it full screen.
How to fix it
From MITRE's mitigation list:
- Use a vetted library or framework that makes properly encoded output easier. MITRE names Microsoft's Anti-XSS library, the OWASP ESAPI Encoding module and Apache Wicket as examples.
- Encode for the context. Parts of one page need different encodings: HTML body, element attributes, URIs, JavaScript sections, CSS. Note that HTML entity encoding is only right for the HTML body. The OWASP XSS Prevention Cheat Sheet covers each context.
- Specify the output encoding. Set the character encoding in the HTTP header. If you do not, browsers guess, which can open subtle XSS attacks.
- Validate input with an allowlist and check all parts of the request, including hidden fields, cookies, headers and the URL, not only fields you expect to display. MITRE states that proper output encoding is the most effective control and validation is defense in depth, since free-form text such as a chat message may legitimately contain special characters.
- Set the session cookie to HttpOnly so script cannot read it through document.cookie. MITRE labels this defense in depth, not a complete solution.
- Reduce the attack surface. Know all the places untrusted input enters, including parameters, cookies, headers, query results, files and external systems.
- Repeat client checks on the server.
- Consider an application firewall as an emergency measure when you cannot change the code, such as third party code, while you fix the cause.
Libraries are part of this too. A rendering component or plugin can carry an XSS flaw in code you did not write. The free in-browser dependency scan at gold.safeguard.sh/scan needs no login, keeps your file on your machine and handles up to 100 dependencies.
Quick check
What is the most effective control against XSS?
Proper output encoding for the context where the data is placed. Input validation adds defense in depth but cannot cover free-form text.
Does HttpOnly stop XSS?
No. It keeps script from reading the session cookie through document.cookie, but the script can still do other harm. MITRE calls it defense in depth.
What is the difference between stored and reflected XSS?
Only how the payload arrives. Stored XSS is saved and served later, reflected XSS is echoed from the request. The consequences are the same.