Summary
mod_verto's WebSocket frame loop intercepts a #-prefixed speed-test protocol (#SPU / #SPB / #SPE) before any authentication check. The declared payload size in #SPU was parsed with atoi() and only rejected non-positive values, so an unauthenticated peer could request up to INT_MAX bytes. The server then wrote roughly size * 10 bytes back during the download phase, on the order of 20 GB per request, yielding strong outbound bandwidth amplification from a short request.
Impact
- A single unauthenticated WebSocket request can compel the server to write tens of gigabytes back to the requester, saturating outbound link capacity and exhausting socket and thread resources.
- Multiple concurrent requests trivially deny service to legitimate users on the same listener.
Affected configurations
Any deployment with a mod_verto WebSocket listener. Default listener ports are :8081 plaintext and :8082 TLS. The speed-test branch is wired unconditionally into the WebSocket frame loop and is not gated by any profile parameter.
Attack prerequisites
Network reach to the verto WebSocket listener. The speed-test branch runs before the JSON-RPC dispatcher and before the authentication gate, so no credentials, prior login, or user interaction are required. TLS does not mitigate: the speed-test branch runs after transport termination, and the amplified write is emitted on the same connection at server expense.
Workarounds
- Restrict the verto WebSocket listener to trusted networks (firewall or bind address).
- Disable
mod_verto outright if it is not in use.
Fix
Two changes in the WebSocket frame loop:
- The
#-prefixed branch now requires an authenticated session; unauthenticated peers can no longer reach the speed-test handler.
- The declared size is parsed with
strtol() and capped at 10 MiB, replacing the previous unbounded atoi(). The cap leaves ample headroom over the ~256 KiB used by the stock verto client.
Credit
Adam Bedard, Security Researcher.
Summary
mod_verto's WebSocket frame loop intercepts a#-prefixed speed-test protocol (#SPU/#SPB/#SPE) before any authentication check. The declared payload size in#SPUwas parsed withatoi()and only rejected non-positive values, so an unauthenticated peer could request up toINT_MAXbytes. The server then wrote roughlysize * 10bytes back during the download phase, on the order of 20 GB per request, yielding strong outbound bandwidth amplification from a short request.Impact
Affected configurations
Any deployment with a
mod_vertoWebSocket listener. Default listener ports are:8081plaintext and:8082TLS. The speed-test branch is wired unconditionally into the WebSocket frame loop and is not gated by any profile parameter.Attack prerequisites
Network reach to the verto WebSocket listener. The speed-test branch runs before the JSON-RPC dispatcher and before the authentication gate, so no credentials, prior login, or user interaction are required. TLS does not mitigate: the speed-test branch runs after transport termination, and the amplified write is emitted on the same connection at server expense.
Workarounds
mod_vertooutright if it is not in use.Fix
Two changes in the WebSocket frame loop:
#-prefixed branch now requires an authenticated session; unauthenticated peers can no longer reach the speed-test handler.strtol()and capped at 10 MiB, replacing the previous unboundedatoi(). The cap leaves ample headroom over the ~256 KiB used by the stock verto client.Credit
Adam Bedard, Security Researcher.