...
| Wiki Markup |
|---|
However, the pattern also introduces additional overheads not seen in sequential execution, including the time and resourceresources required for thread- creation and scheduling, for task processing, for resource allocation and deallocation, and for frequent context switching \[[Lea 2000|AA. Bibliography#Lea 00]\]. Furthermore, an attacker can cause a denial of service (DoS) by overwhelming the system with too many requests all at once, causing the system to become unresponsive rather than degrading gracefully. From a safety perspective, one component can exhaust all resources because of an intermittent error, consequently starving all other components. |
Thread pools allow a system to limit the maximum number of simultaneous requests that it processes to a number that it can comfortably serve , rather than terminating all services when presented with a deluge of requests. Thread pools overcome these issues by controlling the maximum number of worker threads that can execute concurrently. Each object that supports thread pools accepts a Runnable or Callable<T> task and stores it in a temporary queue until resources become available. Additionally, thread life-cycle management overhead is minimized because the threads in a thread pool can be reused and can be efficiently added to or removed from the pool.
Programs that use multiple threads to serve requests should — and security-sensitive programs programs that may be subjected to DoS attacks must — ensure graceful degradation of service during traffic bursts. Use of thread pools is one acceptable approach to meeting this requirement.
...
This noncompliant code example demonstrates the thread-per-message design pattern. The RequestHandler class provides a public static factory method so that callers can obtain its a RequestHandler instance. The handleRequest() method is subsequently invoked to handle each request in its own thread.
| Code Block | ||
|---|---|---|
| ||
class Helper {
public void handle(Socket socket) {
//...
}
}
final class RequestHandler {
private final Helper helper = new Helper();
private final ServerSocket server;
private RequestHandler(int port) throws IOException {
server = new ServerSocket(port);
}
public static RequestHandler newInstance() throws IOException {
return new RequestHandler(0); // Selects next available port
}
public void handleRequest() {
new Thread(new Runnable() {
public void run() {
try {
helper.handle(server.accept());
} catch (IOException e) {
// Forward to handler
}
}
}).start();
}
}
|
The thread-per-message strategy fails to provide graceful degradation of service. As threads are created, processing continues normally until some scarce resource is exhausted. For example, a system may allow only a limited number of open file descriptors , even though additional threads can be created to serve requests. When the scarce resource is memory, the system may fail abruptly, resulting in a denial of serviceDoS.
Compliant Solution (Thread Pool)
...
| Code Block | ||
|---|---|---|
| ||
// class Helper remains unchanged
final class RequestHandler {
private final Helper helper = new Helper();
private final ServerSocket server;
private final ExecutorService exec;
private RequestHandler(int port, int poolSize) throws IOException {
server = new ServerSocket(port);
exec = Executors.newFixedThreadPool(poolSize);
}
public static RequestHandler newInstance(int poolSize)
throws IOException {
return new RequestHandler(0, poolSize);
}
public void handleRequest() {
Future<?> future = exec.submit(new Runnable() {
@Override public void run() {
try {
helper.handle(server.accept());
} catch (IOException e) {
// Forward to handler
}
}
});
}
// ... other methods such as shutting down the thread pool
// and task cancellation ...
}
|
| Wiki Markup |
|---|
According to the Java API documentation for the {{Executor}} interface \[[API 2006|AA. Bibliography#API 06]\] |
Wiki Markup \[The Interfaceinterface {{Executor}} is\] Anan object that executes submitted {{Runnable}} tasks. This interface provides a way of decoupling task submission from the mechanics of how each task will be run, including details of thread use, scheduling, etc. An {{Executor}} is normally used instead of explicitly creating threads.
...
| Wiki Markup |
|---|
The choice of the unbounded {{newFixedThreadPool}} may be inappropriate. Refer to the Java API documentation for guidance on choosing betweenamong the following methods to meet specific design requirements \[[API 2006|AA. Bibliography#API 06]\]: |
...
Using simplistic concurrency primitives to process an unbounded number of requests could result in severe performance degradation, deadlock, or system resource exhaustion and denial of serviceDoS.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
TPS00-J | low | probable | high | P2 | L3 |
Related Guidelines
CWE-405, "Asymmetric Resource Consumption (Amplification)" . Asymmetric resource consumption (amplification) | |
| CWE-410, "Insufficient Resource Pool" . Insufficient resource pool |
Bibliography
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="ba646884b2989e2c-6c24fdb8-44c44af4-b44494aa-e8c06ec856c6fd3549ed1dcf"><ac:plain-text-body><![CDATA[ | [[API 2006 | AA. Bibliography#API 06]] | [Interface Executor | http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executor.html] | ]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="94ae64affb7cbddd-78935b98-4ce040b5-9d36b264-a9a3d520ae1936cb77d47df7"><ac:plain-text-body><![CDATA[ | [[Lea 2000 | AA. Bibliography#Lea 00]] | Section 4.1.3, Thread-Per-Message and ; 4.1.4, Worker Threads | ]]></ac:plain-text-body></ac:structured-macro> | |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="8123d26e481c5a1f-e31ea1ac-45c54647-b8b6b269-8de77a1d77398ca102aed964"><ac:plain-text-body><![CDATA[ | [[Tutorials 2008 | AA. Bibliography#Tutorials 08]] | [Thread Pools | http://java.sun.com/docs/books/tutorial/essential/concurrency/pools.html] | ]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="049c8fa576cb7246-467346e7-47844a20-84c78097-7aa7366fc805c73533a0fa4f"><ac:plain-text-body><![CDATA[ | [[Goetz 2006 | AA. Bibliography#Goetz 06]] | Chapter 8, Applying Thread Pools | ]]></ac:plain-text-body></ac:structured-macro> |
...