{"id":"CVE-2026-33979","aliases":["GHSA-3843-rr4g-m8jq"],"url":"https://o3.security/vulnerability/CVE-2026-33979","summary":"Express XSS Sanitizer: allowedTags/allowedAttributes bypass leads to permissive sanitization (XSS risk)","details":"## Description\nA vulnerability has been identified in express-xss-sanitizer (<= 2.0.1) where restrictive sanitization configurations are silently ignored.\n\nWhen a developer explicitly sets:\n\n  allowedTags: []\n  allowedAttributes: {}\n\nthe library incorrectly treats these values as \"not provided\" due to length/emptiness checks, and falls back to sanitize-html's default configuration.\n\nAs a result, instead of stripping all HTML tags and attributes, the sanitizer allows a permissive set of tags ``` (e.g., <a>, <p>, <div>, etc.) and attributes (e.g., href on <a>)```.\n\nThis behavior violates the expected API contract and may lead to security issues such as content injection or XSS, depending on how the sanitized output is used.\n\n##  Impact\n\nDevelopers intending to fully strip HTML content by providing empty allowedTags or allowedAttributes configurations may unknowingly allow a wide range of HTML elements and attributes.\n\nThis can result in:\n- Injection of unintended HTML content ```(e.g., <div>, <table>, headings)```\n- Injection of links via``` <a href=\"...\">```\n- Potential XSS vectors depending on downstream usage\n\nThe impact depends on how the sanitized output is rendered or consumed, but the root issue is a mismatch between developer intent and actual behavior.\n\n## Proof of Concept\n\n```javascript\nconst { sanitize } = require('express-xss-sanitizer');\nconst sanitizeHtml = require('sanitize-html');\n\nconst input = '<a href=\"http://evil.com\">click</a><p>phish</p>';\n\n// Using express-xss-sanitizer (v2.0.1)\nsanitize(input, { allowedTags: [], allowedAttributes: {} });\n// => '<a href=\"http://evil.com\">click</a><p>phish</p>'\n\n// Expected behavior (sanitize-html directly)\nsanitizeHtml(input, { allowedTags: [], allowedAttributes: {} });\n// => 'clickphish'\n```\n\n## Root Cause\nThe issue was caused by validation logic that checked for non-empty arrays/objects:\n\n- allowedTags required length > 0\n- allowedAttributes required Object.keys(...).length > 0\n\nThis caused empty configurations ([]) and ({}) to be ignored, resulting in fallback to default permissive settings.\n\n## Fix\nThe validation logic has been updated to respect explicitly provided empty configurations.\n\nNow, if allowedTags or allowedAttributes are provided (even if empty), they are passed directly to sanitize-html without being overridden.","published":"2026-03-27T21:29:19.759Z","modified":"2026-08-12T03:51:35.858662035Z","cvss":{"score":8.2,"severity":"HIGH","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N"},"epss":null,"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"npm","name":"express-xss-sanitizer","fixedVersion":"2.0.2"}],"fix":{"url":"https://github.com/AhmedAdelFahim/express-xss-sanitizer/commit/5623009ef11dcf095c163a38dea07b9cc22ad19f","label":"AhmedAdelFahim/express-xss-sanitizer@5623009"},"references":[{"type":"WEB","url":"https://github.com/AhmedAdelFahim/express-xss-sanitizer/releases/tag/v2.0.2"},{"type":"ADVISORY","url":"https://github.com/AhmedAdelFahim/express-xss-sanitizer/security/advisories/GHSA-3843-rr4g-m8jq"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/33xxx/CVE-2026-33979.json"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-33979"},{"type":"FIX","url":"https://github.com/AhmedAdelFahim/express-xss-sanitizer/commit/5623009ef11dcf095c163a38dea07b9cc22ad19f"},{"type":"PACKAGE","url":"https://github.com/AhmedAdelFahim/express-xss-sanitizer"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:35.858662035Z"}}