Jun 15, 2026·6 min read·9 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.
An SSRF vulnerability exists in Flyto2 Core due to improper validation of intermediate HTTP redirect hops. While the initial request target is validated against an SSRF protection policy, the HTTP client library (aiohttp) transparently follows 30x redirects to local, internal, or cloud metadata endpoints without application-level revalidation.
A logic vulnerability exists in @dynatrace-oss/dynatrace-mcp-server prior to version 1.8.7. The create_dynatrace_notebook tool lacks a human-approval gate, allowing an attacker to exploit indirect prompt injection to force the underlying LLM client to create persistent Dynatrace notebooks without the operator's consent.
A critical authentication and authorization bypass vulnerability in the Quarkus Java framework exists due to a parser differential mismatch between the HTTP security policy layer and downstream handlers. By leveraging encoded reserved characters such as semicolons, slashes, and backslashes, attackers can bypass configured path-based security policies to gain unauthorized access to secure administrative endpoints and static resources.
A critical code injection vulnerability exists in @aws/agentcore CLI (AWS AgentCore CLI) during the Bedrock Agent import lifecycle. An authenticated remote attacker with permissions to configure Bedrock collaborator attributes can inject python code by embedding triple-double-quotes (""") inside the collaborationInstruction metadata field. The CLI formats this metadata directly into a Python docstring in a generated main.py file without adequate escaping, leading to arbitrary code execution when the imported agent is run or deployed.
GHSA-WCHH-9X6H-7F6P documents the critical deprecation of the cryptographic library libolm (Olm) and its Python binding wrapper python-olm, which matrix-commander depended upon via its downstream client library matrix-nio. Multiple cryptographic vulnerabilities (timing leaks, side-channels, signature malleability, and protocol confusion) were disclosed in 2022 and 2024. Because libolm is unmaintained, Python clients using matrix-commander are considered cryptographically unsafe until migrating to vodozemac.
An Excessive Data Exposure vulnerability in Easy!Appointments v1.5.2 allows low-privileged administrative users, such as restricted Providers and Secretaries, to harvest unique, stateless appointment hashes belonging to other providers. These hashes act as capability tokens, granting full authorization to reschedule, take over, or delete appointments via stateless endpoints, resulting in a complete Broken Object Level Authorization (BOLA) scenario.