制御されていない資源消費

同時処理数と資源使用量を制限してサービス拒否の危険を減らす

説明

限られた資源の割り当てと使用期間を適切に制御しないと、資源が枯渇してサービス拒否につながる可能性があります。

想定される影響

  • 応答の遅延、停止、サービスの利用不能
  • CPUやメモリなどの過剰な消費による正常な処理の妨害

対処方法

  1. 無制限に割り当てず、資源使用量の上限を定義してください。
  2. 処理の終了時に資源を解放してください。
  3. 使用後のファイルやデータベース接続を閉じてください。
  4. 許容する資源量を超えるリクエストを制限してください。

例

実際のダウンロードを省略したSpringの抜粋です。変更後のカウンターは、一つのコントローラーインスタンスで同期的に実行中のメソッド数を制限します。転送はtry内で完了させてください。非同期転送や複数インスタンス全体の上限は別途管理します。パスの検証、転送サイズ・時間の上限、必要なimportは省略しています。

変更前

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) {
        // 同時実行数を制限せずにダウンロード処理を行う
        File file = new File(fileName);
        // 実際のダウンロード処理は省略
    }
}

変更後

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; // 同時処理数の上限
    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);
            // 実際のダウンロード処理は省略
        } finally {
            activeConnections.decrementAndGet();
        }
        return ResponseEntity.ok("Download started");
    }
}

同時ダウンロードを制限しないと資源が枯渇する可能性があります。変更後は同時処理数を制限して危険を減らします。finallyでカウンターを減らしても、それだけでファイルやネットワーク資源が閉じられるわけではありません。

関連CVE

参考資料