Skip to content

[Critical] Unbounded newCachedThreadPool in ShellSocket leads to Thread Exhaustion/OOM #3

@QiuYucheng2003

Description

@QiuYucheng2003

Bug Description
The ShellSocket class uses a static Executors.newCachedThreadPool() to handle WebSocket messages. Since CachedThreadPool has no upper limit on the number of threads (Integer.MAX_VALUE), and the tasks submitted involve blocking I/O (SSH operations), this design is vulnerable to Thread Exhaustion (UBNT).

Code Analysis

  1. Unbounded Executor: In src/main/java/com/kodcu/ShellSocket.java (Line 23):
    // static shared unbounded pool
    private static final ExecutorService executorService = Executors.newCachedThreadPool();
  2. Uncontrolled Submission: In handleTextMessage (Line 48), a new task is submitted for every incoming WebSocket message without flow control.
  3. Blocking Tasks: The submitted task executes expect.expect(...) (Line 52), which is a blocking I/O operation. If the SSH server is slow or network latency is high, threads will pile up indefinitely.

Impact
Under high concurrency or when multiple users interact with the terminal simultaneously, the application will rapidly spawn thousands of threads, eventually causing the JVM to crash with java.lang.OutOfMemoryError: unable to create new native thread.

Suggested Fix
Replace the unbounded newCachedThreadPool with a bounded thread pool to limit the maximum concurrency.
// Example Fix: Use a Fixed Thread Pool with a reasonable limit
private static final ExecutorService executorService = Executors.newFixedThreadPool(100);

// Or use ThreadPoolExecutor with a RejectionPolicy

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions