{"id":"GHSA-45p5-v273-3qqr","summary":"Vert.x-Web vulnerable to Stored Cross-site Scripting in directory listings via file names","details":"# Description\n\n- In the `StaticHandlerImpl#sendDirectoryListing(...)` method under the `text/html` branch, file and directory names are directly embedded into the `href`, `title`, and link text without proper HTML escaping.\n- As a result, in environments where an attacker can control file names, injecting HTML/JavaScript is possible. Simply accessing the directory listing page will trigger an XSS.\n- Affected Code:\n    - File: `vertx-web/src/main/java/io/vertx/ext/web/handler/impl/StaticHandlerImpl.java`\n    - Lines:\n        - 709–713: `normalizedDir` is constructed without escaping\n        - 714–731: `\u003cli\u003e\u003ca ...\u003e` elements insert file names directly into attributes and body without escaping\n        - 744: parent directory name construction\n        - 746–751: `{directory}`, `{parent}`, and `{files}` are inserted into the HTML template without escaping\n\n# Reproduction Steps\n\n1. Prerequisites:\n    - Directory listing is enabled using `StaticHandler`  \n      (e.g., `StaticHandler.create(\"public\").setDirectoryListing(true)`)\n    - The attacker has the ability to create arbitrary file names under a public directory (e.g., via upload functionality or a shared directory)\n\n2. Create a malicious file name (example for Unix-based OS):\n    - Create an empty file in `public/` with one of the following names:\n      - `\u003cimg src=x onerror=alert('XSS')\u003e.txt`\n      - Or attribute injection: `evil\" onmouseover=\"alert('XSS')\".txt`\n    - Example:\n      ```bash\n      mkdir -p public\n      printf 'test' \u003e \"public/\u003cimg src=x onerror=alert('XSS')\u003e.txt\"\n      ```\n\n3. Start the server (example):\n    - Routing: `router.route(\"/public/*\").handler(StaticHandler.create(\"public\").setDirectoryListing(true));`\n    - Server: `vertx.createHttpServer().requestHandler(router).listen(8890);`\n\n4. Verification request (raw HTTP):\n    ```\n    GET /public/ HTTP/1.1\n    Host: 127.0.0.1:8890\n    Accept: text/html\n    Connection: close\n    ```\n\n5. Example response excerpt:\n    ```html\n    \u003cul id=\"files\"\u003e\n      \u003cli\u003e\n        \u003ca href=\"/public/\u003cimg src=x onerror=alert('XSS')\u003e.txt\"\n           title=\"\u003cimg src=x onerror=alert('XSS')\u003e.txt\"\u003e\n           \u003cimg src=x onerror=alert('XSS')\u003e.txt\n        \u003c/a\u003e\n      \u003c/li\u003e\n      ...\n    \u003c/ul\u003e\n    ```\n\n- When accessing `/public/` in a browser, the unescaped file name is interpreted as HTML, and event handlers such as `onerror` are executed.\n\n# Potential Impact\n\n- **Stored XSS**\n    - Arbitrary JavaScript executes in the browser context of users viewing the listing page\n    - Possible consequences:\n        - Theft of session tokens, JWTs, localStorage contents, or CSRF tokens\n        - Unauthorized actions with admin privileges (user creation, permission changes, settings modifications)\n        - Watering hole attacks, including malware distribution or malicious script injection to other pages\n\n- **Common Conditions That Make Exploitation Easier**\n    - Uploaded files are served directly under a publicly accessible directory\n    - Shared/synced directories (e.g., NFS, SMB, WebDAV, or cloud sync) are exposed\n    - ZIP/TAR archives are extracted directly under the webroot and directory listing is enabled in production environments\n\n# Similar CVEs Previously Reported\n\n- CVE‑2024‑32966  \n- CVE‑2019‑15603","aliases":["CVE-2025-11966"],"modified":"2026-07-17T21:15:17.811542476Z","published":"2025-10-22T19:38:11Z","database_specific":{"nvd_published_at":"2025-10-22T15:15:31Z","cwe_ids":["CWE-79"],"severity":"LOW","github_reviewed":true,"github_reviewed_at":"2025-10-22T19:38:11Z"},"references":[{"type":"WEB","url":"https://github.com/vert-x3/vertx-web/security/advisories/GHSA-45p5-v273-3qqr"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2025-11966"},{"type":"PACKAGE","url":"https://github.com/vert-x3/vertx-web"},{"type":"WEB","url":"https://gitlab.eclipse.org/security/vulnerability-reports/-/issues/303"}],"affected":[{"package":{"name":"io.vertx:vertx-web","ecosystem":"Maven","purl":"pkg:maven/io.vertx/vertx-web"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"4.5.22"}]}],"versions":["3.0.0","3.0.0-milestone6","3.1.0","3.2.0","3.2.1","3.3.0","3.3.0.CR1","3.3.0.CR2","3.3.1","3.3.2","3.3.3","3.4.0","3.4.0.Beta1","3.4.1","3.4.2","3.5.0","3.5.0.Beta1","3.5.1","3.5.2","3.5.2.CR1","3.5.2.CR2","3.5.2.CR3","3.5.3","3.5.3.CR1","3.5.4","3.6.0","3.6.0.CR1","3.6.0.CR2","3.6.1","3.6.2","3.6.3","3.7.0","3.7.1","3.8.0","3.8.1","3.8.2","3.8.3","3.8.3-01","3.8.4","3.8.5","3.9.0","3.9.1","3.9.10","3.9.11","3.9.12","3.9.13","3.9.14","3.9.15","3.9.16","3.9.2","3.9.3","3.9.4","3.9.5","3.9.6","3.9.7","3.9.8","3.9.9","4.0.0","4.0.0-milestone1","4.0.0-milestone2","4.0.0-milestone3","4.0.0-milestone4","4.0.0-milestone5","4.0.0.Beta1","4.0.0.Beta2","4.0.0.Beta3","4.0.0.CR1","4.0.0.CR2","4.0.1","4.0.2","4.0.3","4.1.0","4.1.0.Beta1","4.1.0.CR1","4.1.0.CR2","4.1.1","4.1.2","4.1.3","4.1.4","4.1.5","4.1.6","4.1.7","4.1.8","4.2.0","4.2.0.Beta1","4.2.0.CR1","4.2.1","4.2.2","4.2.3","4.2.4","4.2.5","4.2.6","4.2.7","4.3.0","4.3.1","4.3.2","4.3.3","4.3.4","4.3.5","4.3.6","4.3.7","4.3.8","4.4.0","4.4.1","4.4.2","4.4.3","4.4.4","4.4.5","4.4.6","4.4.7","4.4.8","4.4.9","4.5.0","4.5.1","4.5.10","4.5.11","4.5.12","4.5.13","4.5.14","4.5.15","4.5.16","4.5.17","4.5.18","4.5.19","4.5.2","4.5.20","4.5.21","4.5.3","4.5.4","4.5.5","4.5.6","4.5.7","4.5.8","4.5.9"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2025/10/GHSA-45p5-v273-3qqr/GHSA-45p5-v273-3qqr.json"}},{"package":{"name":"io.vertx:vertx-web","ecosystem":"Maven","purl":"pkg:maven/io.vertx/vertx-web"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"5.0.0"},{"fixed":"5.0.5"}]}],"versions":["5.0.0","5.0.1","5.0.2","5.0.3","5.0.4"],"database_specific":{"last_known_affected_version_range":"\u003c= 5.0.4","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2025/10/GHSA-45p5-v273-3qqr/GHSA-45p5-v273-3qqr.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:N"},{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:N/VC:L/VI:L/VA:N/SC:L/SI:L/SA:N"}]}