Uncontrolled resource consumption

Limit concurrent work and resource use to reduce denial-of-service risk

Description

Failing to control the allocation and lifetime of limited resources can exhaust them and cause denial of service.

Potential impact

  • Slow responses, crashes or unavailable service
  • Excessive CPU, memory or other resource use that prevents normal operation

Remediation

  1. Define maximum allocations instead of allowing unlimited resource use.
  2. Release resources when work finishes.
  3. Close files and database connections after use.
  4. Throttle requests that exceed the allowed resource budget.

Examples

These Spring excerpts omit the actual download. The revised counter limits synchronous method executions in one controller instance. The transfer must finish inside try; asynchronous transfers and aggregate limits across instances require separate handling. Path validation, transfer size/time limits and necessary imports are omitted.

Before

java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FileDownloadController {
    @GetMapping("/download")
    public void downloadFile(@RequestParam String fileName) {
        // Download work would run without a concurrency limit
        File file = new File(fileName);
        // Actual download logic omitted
    }
}

After

java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FileDownloadController {
    private static final int MAX_CONNECTIONS = 10; // Concurrent-work limit
    private AtomicInteger activeConnections = new AtomicInteger(0);

    @GetMapping("/download")
    public ResponseEntity<String> downloadFile(@RequestParam String fileName) {
        if (activeConnections.incrementAndGet() > MAX_CONNECTIONS) {
            activeConnections.decrementAndGet();
            return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).body("Too Many Requests");
        }

        try {
            File file = new File(fileName);
            // Actual download logic omitted
        } finally {
            activeConnections.decrementAndGet();
        }
        return ResponseEntity.ok("Download started");
    }
}

Unbounded simultaneous downloads can exhaust resources. The revised counter reduces this risk by limiting concurrent work. Decrementing it in finally does not itself close file or network resources.

Related CVEs

References