The vulnerability exists in the sendDirectoryListing method of the StaticHandlerImpl class. The provided vulnerability description explicitly points to this method and the lack of HTML escaping for file names when generating directory listings. To confirm this, I analyzed the commits that patched the vulnerability in versions 4.5.22 and 5.0.5 of vertx-web. The commits f2dbc2a364e6dddcfe50f1dd66d27b8b3e715368 and 121d09c1c34ff23f16d0df63b988579ca9f3f970 clearly show the fix. Before the patch, the file variable (containing the filename) was concatenated directly into the HTML string. The patch introduces calls to Utils.encodeUriPath for the href attribute and Utils.escapeHTML for the title attribute and the link text. This prevents the browser from interpreting malicious file names as code. Therefore, the sendDirectoryListing function is the exact location of the vulnerability, as it is responsible for processing the untrusted file names and generating the unsafe HTML output.
io.vertx.ext.web.handler.impl.StaticHandlerImpl.sendDirectoryListingvertx-web/src/main/java/io/vertx/ext/web/handler/impl/StaticHandlerImpl.java
Start the server (example):
router.route("/public/*").handler(StaticHandler.create("public").setDirectoryListing(true));vertx.createHttpServer().requestHandler(router).listen(8890);Verification request (raw HTTP):
GET /public/ HTTP/1.1
Host: 127.0.0.1:8890
Accept: text/html
Connection: close
Example response excerpt:
<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>
/public/ in a browser, the unescaped file name is interpreted as HTML, and event handlers such as onerror are executed.Stored XSS
Common Conditions That Make Exploitation Easier
Ongoing coverage of React2Shell
| Package Name | Ecosystem | Vulnerable Versions | First Patched Version |
|---|---|---|---|
| io.vertx:vertx-web | maven | < 4.5.22 | 4.5.22 |
| io.vertx:vertx-web | maven | >= 5.0.0, <= 5.0.4 | 5.0.5 |