Jun 15, 2026·6 min read·2 visits
Unvalidated packet length fields in cbssh allow a malicious SSH server to crash the client application via OutOfMemoryError by sending an inflated size header.
A denial of service vulnerability in the ConnectBot SSH Client Library (cbssh) up to version 0.3.0 allows remote attackers to cause uncontrolled resource consumption. The library uses Kaitai Struct to parse incoming binary streams, but failed to validate the declared length of SSH fields against the physical stream size, leading to excessive memory allocation and OutOfMemoryError crashes.
The ConnectBot SSH Client Library (cbssh) is a Kotlin-based implementation of the SSH protocol designed for integration into mobile and desktop applications. To parse complex binary layouts defined by the SSH protocol, the library relies on Kaitai Struct specifications (.ksy files) compiled into Kotlin source code. These generated parsers process SSH packets, including key exchange, authentication messages, and session payloads.
In all versions of cbssh up to and including v0.3.0, the generated parsing routines trusted packet length headers without verifying actual physical payload sizes. This trust allows a remote peer, such as an adversarial SSH server, to transmit small packets containing disproportionately large declared field lengths. When the library attempts to allocate buffers or initiate loops based on these values, the application crashes due to resource exhaustion.
This vulnerability is classified under CWE-770 (Allocation of Resources Without Limits or Throttling) and CWE-400 (Uncontrolled Resource Consumption). The attack surface resides entirely in the initial protocol parser, which operates on unauthenticated input data prior to completing cryptographic handshakes or user authentication. Consequently, any application utilizing an affected version of cbssh to connect to an untrusted SSH endpoint is vulnerable to remote, unauthenticated Denial of Service.
The root cause of this vulnerability lies in the structural definitions of the Kaitai Struct files (.ksy) used to generate the parser classes. Kaitai Struct reads declarative specifications and generates corresponding parsing code in Kotlin. In the vulnerable versions, fields representing lengths (such as strings, byte arrays, and lists) were defined as simple 32-bit unsigned integers (u4) without verification constraints.
When a variable-length field like a byte_string or ascii_string is processed, the parser first reads the 4-byte length prefix. It then immediately invokes a read operation of that exact size to ingest the succeeding payload or allocates a collection of that size. Because the parser has no knowledge of how many bytes are actually left in the network or file buffer, it executes the allocation request blindly.
An attacker can trigger this allocation vulnerability by sending a short packet with an inflated length field, such as 0xFFFFFFFF. The underlying Java Virtual Machine (JVM) or Android runtime attempt to allocate a byte array of the requested size. This request immediately exceeds the maximum heap limit, generating an unhandled java.lang.OutOfMemoryError that terminates the process.
The vulnerability was addressed in version 0.3.1 by adding validation expressions directly inside the Kaitai Struct definition files. The patch introduces valid: expr: _ <= _io.size - _io.pos rules to every length header field. These checks ensure that the declared length of a field does not exceed the remaining number of bytes available in the input stream buffer.
For example, in byte_string.ksy, the following constraint was added:
seq:
- id: len_data
type: u4
valid:
expr: _ <= _io.size - _io.pos
- id: data
size: len_dataThis validation requires that the read value (_) is less than or equal to the total stream size (_io.size) minus the current position (_io.pos). If the value violates this logic, the parser throws a validation exception immediately, halting the process before allocating memory.
For collections where a loop occurs, such as in ssh_agent_identities_answer.ksy, the fix enforces bounds by dividing the remaining stream size by the minimum possible byte size of an element. The condition _ <= (_io.size - _io.pos) / 8 ensures that if a response claims to contain a large number of keys, the input stream must contain at least 8 bytes per key to satisfy the request. This mathematically prevents arbitrary loop iteration allocation based on falsified counts.
Exploitation of this vulnerability is straightforward and requires no prior authentication or administrative privileges. The attacker must operate an adversarial SSH server or execute a machine-in-the-middle attack to intercept and modify traffic. The target application initiates a connection to this server, progressing through the early stages of the SSH protocol negotiation.
During the exchange, the server transmits a crafted SSH packet, such as SSH_MSG_USERAUTH_INFO_REQUEST, containing an inflated length descriptor. The packet payload size may be less than 100 bytes, but the internal field representing the prompt count or string size is hardcoded to a large value like 0xFFFFFFFF. The client receives the packet, processes the headers, and hits the unvalidated allocation point.
Since the actual stream contains only a few remaining bytes, any legitimate parser should fail immediately due to premature end-of-file conditions. However, because the allocation happens before the read attempt, the system crashes on allocation rather than parsing failure. The expected outcome is an instantaneous process termination, leading to a complete denial of service for the client software.
The impact of GHSA-CH3Q-CW5R-F4HG is limited to client-side Denial of Service (DoS). While the vulnerability allows unauthenticated remote actors to trigger crashes, it does not provide a direct vector for remote code execution (RCE) or information disclosure. The crash is caused by a standard JVM OutOfMemoryError exception, which is safely caught or processed as a fatal error by the operating system or application wrapper.
No memory corruption occurs because the JVM enforces strict type safety and array bounds during runtime, preventing traditional heap exploitation techniques. The risk is high for systems relying on persistent SSH connectivity for automation, background synchronization, or interactive remote shells, where a crash disrupts business logic.
This vulnerability is particularly significant for Android applications utilizing ConnectBot's client library. Mobile devices often have restricted heap limits per application, making them highly susceptible to memory exhaustion attacks. An attacker can repeatedly crash the application, preventing the user from establishing any secure remote session.
The primary remediation strategy is upgrading the cbssh library dependency to version v0.3.1 or later. This version incorporates the updated Kaitai Struct specifications which perform validation before allocating buffer resources. Developers must update their build configuration files to use the patched version.
// build.gradle (Example dependency configuration)
implementations 'org.connectbot:cbssh:0.3.1'If upgrading is not immediately possible, application developers can mitigate the issue by wrapping SSH connection routines in robust exception handlers that catch java.lang.OutOfMemoryError or general throwables. While this prevents the entire application from crashing, it still terminates the specific SSH thread or connection state, leaving the denial of service partially effective.
For teams utilizing Kaitai Struct in other projects, this vulnerability serves as a key lesson in secure parser design. All variable-length fields or collection sizes read from external streams must be bounded against both static limits (such as a maximum allowed string length) and dynamic limits (such as the remaining size of the input stream).
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Attribute | Detail |
|---|---|
| CWE ID | CWE-770 |
| Attack Vector | Network (Remote) |
| CVSS Severity | Medium-High (7.5) |
| Impact | Denial of Service (DoS) via OutOfMemoryError |
| Exploit Status | Proof-of-Concept |
| Affected Versions | <= v0.3.0 |
| Patched Version | v0.3.1 |
The software allocates memory or other resources based on a user-controlled size before verifying that the request size is valid or within acceptable limits.
Improper validation of backslash character separators in esbuild's local development server allows path traversal on Windows systems.
An issue was discovered in the Deno integration of the esbuild package. The module fails to verify the integrity of downloaded native binary packages from NPM registries before writing and executing them on the local filesystem. This allows an attacker who controls the NPM_CONFIG_REGISTRY environment variable or intercepts the network connection to execute arbitrary native code on the host machine.
A thread-safety vulnerability exists in the PyO3 library versions prior to 0.29.0 due to a missing Sync trait bound on closure type parameters. This omission allows safe Rust code to register non-thread-safe closures as Python callables, leading to concurrent shared mutation and data races during multithreaded execution.
An integer overflow and excessive memory allocation vulnerability in the Distinguished Encoding Rules (DER) private-key parser of ConnectBot SSH Client Library (connectbot/cbssh) allows a local attacker to cause a Denial of Service (DoS) via process termination. By inducing an application utilizing the library to parse a malformed DER-encoded private key file, the library attempts massive memory allocations, triggering an uncaught OutOfMemoryError on the JVM.
An unauthenticated remote code execution (RCE) vulnerability exists in phoenix_storybook versions 0.5.0 through 1.0.x due to improper input sanitization during HEEx template generation. By sending crafted WebSocket messages, an attacker can escape HTML attribute boundaries and execute arbitrary Elixir code.
An unauthenticated Denial-of-Service (DoS) vulnerability exists in phoenix_storybook versions 0.2.0 through 1.0.11 due to allocation of resources without limits (CWE-770). The application dynamically converts user-supplied parameter keys to atoms, leading to BEAM Atom Table exhaustion and immediate virtual machine crash.