{"id":"GHSA-2r2c-cx56-8933","title":"JLine3 Telnet server: Unauthenticated Remote DoS via Unbounded Telnet NAWS Terminal Geometry","summary":"JLine3 Telnet server: Unauthenticated Remote DoS via Unbounded Telnet NAWS Terminal Geometry","severity":"high","cvss":7.5,"cwe":["CWE-400"],"vendor":"jline","product":"org.jline:jline-remote-telnet","ecosystem":"maven","affected":["org.jline:jline-remote-telnet < 4.2.1"],"patched":["org.jline:jline-remote-telnet 4.2.1"],"published":"2026-06-18","updated":"2026-06-18","source":"GHSA","sourceUrl":"https://github.com/advisories/GHSA-2r2c-cx56-8933","references":[{"url":"https://github.com/jline/jline3/security/advisories/GHSA-2r2c-cx56-8933"},{"url":"https://github.com/advisories/GHSA-2r2c-cx56-8933"}],"tags":["ghsa","maven"],"ingestedAt":"2026-06-29T14:31:46.998Z","slug":"GHSA-2r2c-cx56-8933","body":"## Overview\n\n### Summary\n\nThe JLine3 Telnet server (`remote-telnet` module) does not apply an upper bound to\nterminal dimensions received via the Telnet NAWS (Negotiate About Window Size) option.\nAn unauthenticated remote attacker can send a NAWS subnegotiation advertising a\n65535×65535 terminal and repeatedly alternate values to trigger continuous, expensive\nrendering work on the server, causing CPU exhaustion and denial of service.\n\n### Details\n\n`TelnetIO.handleNAWS()` (TelnetIO.java:856-879) reads the client-supplied width and\nheight as 16-bit unsigned integers and passes them to `setTerminalGeometry()`:\n\n```java\n// TelnetIO.java:869-875\nprivate void setTerminalGeometry(int columns, int rows) {\n    if (columns < SMALLEST_BELIEVABLE_WIDTH) columns = DEFAULT_WIDTH;  // lower bound only\n    if (rows    < SMALLEST_BELIEVABLE_HEIGHT) rows    = DEFAULT_HEIGHT;\n    connectionData.setTerminalGeometry(columns, rows);\n    connection.processConnectionEvent(\n        new ConnectionEvent(connection, ConnectionEvent.Type.CONNECTION_TERMINAL_GEOMETRY_CHANGED));\n}\n```\n\nOnly a *lower* bound is enforced (minimum 20 columns / 6 rows). Values up to 65535 are\naccepted and stored. The geometry change event propagates to Telnet.java:153-158 where\nit calls:\n\n    terminal.setSize(new Size(65535, 65535));\n    terminal.raise(Signal.WINCH);\n\nThe WINCH signal triggers `LineReaderImpl.handleSignal()` → `redisplay()`. Inside\n`redisplay()`, multiple paths iterate up to `size.getColumns()` times:\n\n- `freshLine()` (LineReaderImpl.java:937,953): loops `size.getColumns()-1` = **65534\n  iterations**, building and writing a space-padding string across the network socket.\n- `columnSplitLength(terminal, size.getColumns(), ...)`: called multiple times,\n  each processing all characters against the 65535-wide line width.\n\nBecause WINCH only fires on *change*, the attacker alternates between two large values\n(e.g., 65535 and 65534) to trigger an unlimited stream of expensive render cycles.\nNo authentication is required; the NAWS option is negotiated before any login sequence.\n\nAffected source files:\n- `remote-telnet/src/main/java/org/jline/builtins/telnet/TelnetIO.java` lines 856-879\n- `remote-telnet/src/main/java/org/jline/builtins/telnet/Telnet.java` lines 140-175\n- `reader/src/main/java/org/jline/reader/impl/LineReaderImpl.java` lines 929-962, 1293-1313\n\n### PoC\n\nSend the following two raw Telnet packets in a loop to a running JLine Telnet server.\nNo login or authentication is required.\n\nPacket 1 — NAWS 65535 × 65535:\n  FF FA 1F FF FF FF FF FF F0\n  (IAC SB NAWS 0xFF 0xFF 0xFF 0xFF IAC SE)\n\nPacket 2 — NAWS 65534 × 65534:\n  FF FA 1F FF FE FF FE FF F0\n  (IAC SB NAWS 0xFF 0xFE 0xFF 0xFE IAC SE)\n\nSending these alternately at ~10 packets/second is sufficient to peg one CPU core on\nthe server. The server remains in this state for as long as the connection is open.\n\nReproduction environment:\n- JLine3 built from current master on x86_64 Linux, OpenJDK 25.0.2\n- `remote-telnet` module started with its default `Telnet` server configuration\n- Test confirmed by source-code analysis and tracing the call chain at runtime\n\n### Impact\n\n**Type**: Denial of Service (CPU exhaustion)\n**Who is affected**: Any application that embeds the JLine3 `remote-telnet` module and\nexposes its Telnet server on a network interface. The attacker requires no credentials.\nA single connection making ~10 alternating NAWS packets per second fully occupies the\nconnection-handling thread and produces continuous I/O on the server's output stream.\nBecause connection threads are re-used for the life of the session, one attacker per\navailable connection slot can deny service to all users of that slot.\n\n### Credits\nThis issue was identified by Michał Majchrowicz and Marcin Wyczechowski, members of the AFINE Team.\n\n## Affected packages\n\n- `org.jline:jline-remote-telnet < 4.2.1`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `org.jline:jline-remote-telnet 4.2.1`","depth":"twilight","depthScore":41,"depthScoreParts":{"impact":41.3,"likelihood":0,"exploitation":0,"ransomware":0},"changes":[]}