Safeguard
Application Security•

CWE-80 Basic XSS: Unescaped Script-Related HTML Characters

Characters like angle brackets and ampersands reach a web page unescaped. CWE-80 is the plain version of XSS, and encoding on output is the core fix.

Safeguard Security Team
3 min read

CWE-80 is the basic form of cross-site scripting. The product takes input from an upstream component but does not neutralize, or incorrectly neutralizes, special characters such as angle brackets and the ampersand that could be read as web-scripting elements when they reach a component that processes web pages.

It belongs to the same family as CWE-79, and applies to any page that shows user-supplied text.

How it happens

A page is built from text. If a value from a user lands in that text without escaping, the browser cannot tell the user's characters from the page's own markup. An attacker inserts special characters that are processed client-side in the context of the user's session.

A short Node example:

// Vulnerable
res.send("<p>Hello " + req.query.name + "</p>");

// Fixed: escape for HTML body context
const escapeHtml = s => s.replace(/&/g, "&amp;")
  .replace(/</g, "&lt;").replace(/>/g, "&gt;")
  .replace(/"/g, "&quot;").replace(/'/g, "&#39;");
res.send("<p>Hello " + escapeHtml(req.query.name) + "</p>");

The observed examples are from the early 2000s, and show the usual entry points: CVE-2002-0938 is XSS in a parameter in a link, CVE-2002-1495 is XSS in a web-based email product via attachment filenames, CVE-2003-1136 is HTML injection in a posted message and CVE-2004-2171 is XSS not quoted in an error page. See CVE-2002-0938, CVE-2002-1495, CVE-2003-1136 and CVE-2004-2171.

What an attacker gains

MITRE lists confidentiality, integrity and availability: reading application data and executing unauthorized code or commands, all within the victim's session.

How to find it

MITRE lists automated static analysis (SAST), which can find some instances by analyzing source or compiled code and modeling data flow, without running the program. Pair it with manual testing that feeds special characters to every field and checks how they come back in the page.

How to fix it

  1. Check all input against an allowlist. Define the specific characters and format allowed. Neutralize all data in the request, including hidden fields, cookies, headers and the URL, not only fields you expect to show. A field that is not reflected today may be reflected by a future developer.
  2. Specify an output encoding. Use one the downstream component handles, such as UTF-8. When no encoding is declared, browsers guess, and inconsistent encodings let attackers slip characters past filters.
  3. Encode on output for the context the data lands in.

Quick check

Why validate fields that are not displayed?

A field that is not reflected now may be used later by another developer, and the application server may reflect request data you did not expect.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.