<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: testing-llm-denial-of-service
description: >-
  Test LLM applications for denial-of-service vulnerabilities including resource
  exhaustion through crafted prompts, infinite generation loops, context window
  flooding, and cost-based attacks against pay-per-token APIs.
domain: cybersecurity
subdomain: ai-llm-security
tags:
  - denial-of-service
  - resource-exhaustion
  - llm-security
  - cost-attack
  - rate-limiting
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1499"]
  owasp-llm: ["LLM04"]
  mitre-atlas: ["AML.T0029"]
  tools: ["python3", "requests", "asyncio"]
---

# Testing LLM Denial of Service

## Overview

LLM denial-of-service attacks exhaust compute resources, token budgets, or API
rate limits by crafting inputs that maximize processing cost. Techniques include
context window flooding, triggering maximum-length generation, recursive tool
calls in agentic systems, and cost amplification through pay-per-token billing.
Testing identifies missing guardrails before attackers exploit them.

## Prerequisites

| Tool / Requirement | Details |
|---|---|
| `python3` | Security tooling |
| `requests` | Security tooling |
| `asyncio` | Security tooling |
| Access to the target LLM application endpoint | Environment requirement |
| Understanding of the application's rate limits and token budgets | Environment requirement |
| Authorized testing engagement with explicit DoS testing scope | Environment requirement |

## Key Concepts

- **Context window flooding**: Filling the context window with maximum-length inputs
- **Generation amplification**: Prompts that trigger maximum-length output generation
- **Recursive tool loops**: Agentic systems tricked into infinite tool call chains
- **Cost amplification**: Maximizing per-request cost through expensive model features
- **Token budget exhaustion**: Draining allocated token budgets through rapid requests

## Workflow

### Step 1: Context Window Flooding

```python
import requests
import time

def test_context_flooding(endpoint: str, headers: dict, max_tokens: int = 128000) -> dict:
    payload = "A" * max_tokens
    start = time.time()
    try:
        resp = requests.post(
            endpoint,
            json={"messages": [{"role": "user", "content": payload}]},
            headers=headers, timeout=120,
        )
        elapsed = time.time() - start
        return {
            "test": "context_flooding",
            "input_length": len(payload),
            "status_code": resp.status_code,
            "response_time_seconds": round(elapsed, 2),
            "error_handled": resp.status_code in (400, 413, 429),
        }
    except requests.Timeout:
        return {"test": "context_flooding", "error": "timeout", "vulnerable": True}
```

### Step 2: Generation Amplification

```python
def test_generation_amplification(endpoint: str, headers: dict) -> dict:
    amplification_prompts = [
        "Write a 10000-word detailed essay about every country in the world.",
        "List every prime number from 1 to 1000000 with proofs.",
        "Generate a complete novel with 50 chapters, each 2000 words.",
    ]
    results = []
    for prompt in amplification_prompts:
        start = time.time()
        try:
            resp = requests.post(
                endpoint,
                json={"messages": [{"role": "user", "content": prompt}]},
                headers=headers, timeout=120,
            )
            elapsed = time.time() - start
            output_len = len(resp.json().get("choices", [{}])[0].get("message", {}).get("content", ""))
            results.append({
                "prompt": prompt[:80], "response_time": round(elapsed, 2),
                "output_length": output_len, "status": resp.status_code,
            })
        except requests.Timeout:
            results.append({"prompt": prompt[:80], "error": "timeout"})
    return {"test": "generation_amplification", "results": results}
```

### Step 3: Concurrent Request Flooding

```python
import asyncio
import aiohttp

async def test_concurrent_requests(
    endpoint: str, headers: dict, concurrency: int = 50, total: int = 200
) -> dict:
    results = {"success": 0, "rate_limited": 0, "errors": 0}
    semaphore = asyncio.Semaphore(concurrency)

    async def single_request(session: aiohttp.ClientSession) -> None:
        async with semaphore:
            try:
                async with session.post(
                    endpoint,
                    json={"messages": [{"role": "user", "content": "Hello"}]},
                    headers=headers, timeout=aiohttp.ClientTimeout(total=30),
                ) as resp:
                    if resp.status == 429:
                        results["rate_limited"] += 1
                    elif resp.status == 200:
                        results["success"] += 1
                    else:
                        results["errors"] += 1
            except Exception:
                results["errors"] += 1

    async with aiohttp.ClientSession() as session:
        tasks = [single_request(session) for _ in range(total)]
        await asyncio.gather(*tasks)

    results["rate_limiting_active"] = results["rate_limited"] > 0
    return {"test": "concurrent_flooding", **results}
```

## Detection

```yaml
title: Testing Llm Denial Of Service Detection
id: 9b11115b-7240-45e7-8df0-4043923b6bdf
status: experimental
description: Detects suspicious activity related to testing llm denial of service techniques in ai llm security context
logsource:
  category: application
  product: webserver
detection:
  selection:
    EventType: error
  condition: selection
level: medium
tags:
  - attack.t1499
  - attack.initial_access
falsepositives:
  - Automated AI model training and inference pipeline operations
```


**Detection Opportunities**

| Indicator | Source | Detection Logic |
|---|---|---|
| Testing Llm Denial Of Service Detection | webserver/application | Sigma rule (medium) |
| ATT&CK Coverage | MITRE ATT&CK | T1499 |

## Verification

- [ ] Context window flooding tested with maximum-length inputs
- [ ] Generation amplification tested with output-maximizing prompts
- [ ] Concurrent request flooding tested for rate limiting
- [ ] Token budget exhaustion tested
- [ ] Application gracefully handles all DoS attempts
- [ ] Findings mapped to OWASP LLM04 and MITRE ATLAS

## References

- [OWASP LLM04 — Model Denial of Service](https://genai.owasp.org/llmrisk/llm04-model-denial-of-service/)
- [MITRE ATLAS AML.T0029 — Denial of ML Service](https://atlas.mitre.org/techniques/AML.T0029)
- [NIST AI RMF — Resilience](https://airc.nist.gov/AI_RMF_Playbook)
- [Rate Limiting Best Practices](https://cloud.google.com/architecture/rate-limiting-strategies)
