{"id":"CVE-2026-56741","aliases":["GHSA-2r2c-cx56-8933"],"url":"https://o3.security/vulnerability/CVE-2026-56741","summary":"JLine: Unauthenticated Remote DoS via Unbounded Telnet NAWS Terminal Geometry","details":"### 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.","published":"2026-07-17T21:15:14.732Z","modified":"2026-08-20T10:17:15.454630Z","cvss":{"score":7.5,"severity":"HIGH","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"},"epss":{"score":0.00595,"percentile":0.46952,"asOf":"2026-09-17"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"Maven","name":"org.jline:jline-remote-telnet","fixedVersion":"4.2.1"},{"ecosystem":"Maven","name":"org.jline:jline-remote-telnet","fixedVersion":"4.0.16"},{"ecosystem":"Maven","name":"org.jline:jline-remote-telnet","fixedVersion":"3.30.14"}],"fix":{"url":"https://github.com/jline/jline3/commit/3ea9cad8699714dc072fade29d36be0d1e23d708","label":"jline/jline3@3ea9cad"},"references":[{"type":"WEB","url":"https://github.com/jline/jline3/releases/tag/4.0.16"},{"type":"WEB","url":"https://github.com/jline/jline3/releases/tag/4.2.1"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/56xxx/CVE-2026-56741.json"},{"type":"ADVISORY","url":"https://github.com/jline/jline3/security/advisories/GHSA-2r2c-cx56-8933"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-56741"},{"type":"FIX","url":"https://github.com/jline/jline3/commit/3ea9cad8699714dc072fade29d36be0d1e23d708"},{"type":"FIX","url":"https://github.com/jline/jline3/commit/733eb353dca7b0ea0252e724445b6defa29c393e"},{"type":"FIX","url":"https://github.com/jline/jline3/commit/86b7ba7801988aadb1a67555629522a71d603bd3"},{"type":"FIX","url":"https://github.com/jline/jline3/pull/2000"},{"type":"PACKAGE","url":"https://github.com/jline/jline3"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-20T10:17:15.454630Z"}}