CWE-81 covers a product that receives input from an upstream component but does not neutralize special characters that could be read as web-scripting elements when they are sent to an error page.
Error pages are easy to forget. Every web server and framework has them, and many show the URL or message that caused the error.
How it happens
Error pages include customized 403 Forbidden or 404 Not Found pages. When an attacker can trigger an error whose message contains script syntax from the attacker's input, cross-site scripting becomes possible. The attacker only needs a victim to open a crafted link that produces the error.
A small Python example:
@app.errorhandler(404)
def not_found(e):
# Vulnerable: echoes the requested path unescaped
return "<p>No page at " + request.path + "</p>", 404
# Safer: do not echo input, or escape it
@app.errorhandler(404)
def not_found(e):
return "<p>Page not found.</p>", 404
The observed examples include CVE-2002-0840 (XSS in the default error page from the Host header), CVE-2002-1053 (XSS in an error message) and CVE-2002-1700 (XSS in an error page from a targeted parameter). See CVE-2002-0840, CVE-2002-1053 and CVE-2002-1700. Note that one of them came from a header, not a form field.
A related, more recent record is in the CWE-79 list: CVE-2021-25963 describes a Python-based e-commerce platform that did not escape returned content on error pages.
What an attacker gains
MITRE lists confidentiality, integrity and availability, through reading application data and executing unauthorized code or commands in the victim's browser.
How to find it
MITRE lists automated static analysis (SAST), which models data flow in source or compiled code. Add manual testing: request nonexistent pages, send bad headers and break parameters on purpose, and read each error page for echoed input.
How to fix it
- Do not write user-controlled input to error pages. This is MITRE's first mitigation and the simplest.
- If you must show it, check against an allowlist and neutralize all request data, including headers, cookies, hidden fields and the URL.
- Encode on output for the page context.
Quick check
What is the simplest way to avoid CWE-81?
Do not put user-controlled input on error pages at all.