FlawOpen

flawopen.com/Teardowns/cve-2026-76504-cisco-sdwan-api-authentication-bypass

● CVE-2026-76504 · CVSS 9.8[1] · Критический
Исследования · FlawOpen

CVE-2026-76504: обход аутентификации в Cisco SD-WAN Manager

CVE-2026-76504 позволяет удалённому неаутентифицированному злоумышленнику обойти правило аутентификации API в Cisco Catalyst SD-WAN Manager и получить доступ к API с правами администратора. Cisco подтверждает активную эксплуатацию; обновите систему до исправленной версии своей ветки и проверьте менеджер на компрометацию.[1], [5]

Вектор CVSSCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H[1]
💡 Простыми словами (ELI5)

Представьте защищённую дверь, проверка которой распознаёт только один вариант написания адреса. Злоумышленник меняет написание с помощью URI-кодирования: одна часть системы распознаёт ту же дверь, а правило безопасности — нет. По данным Cisco, из-за этого запрос мог обойти аутентификацию и попасть к API от имени администратора. Исправление должно единообразно обрабатывать адрес и применять одно правило доступа; для операторов поддерживаемое Cisco решение — обновление ПО.[1]

Ключевые понятия и термины

URI-кодирование
Представление символов пути URL в виде байтов с процентным кодированием. Все уровни должны одинаково декодировать и сравнивать путь.[1], [7]
Обход аутентификации
Запрос достигает защищённой функции, хотя система не установила личность вызывающей стороны требуемым способом.[1]
Правило API-сессии
Правило менеджера, проверяющее наличие действительной аутентифицированной сессии API до доступа к конечной точке.[1]
CWE-177
Неправильная обработка кодирования URL: непоследовательная обработка закодированных данных URL может нарушить решение безопасности. Cisco присваивает эту слабость CVE.[1], [7]

Связи со стандартами

Анализ первопричины

Cisco связывает CVE-2026-76504 с неправильной обработкой URI-кодирования в HTTP-запросах при сессионной аутентификации API Catalyst SD-WAN Manager. Специально сформированный запрос может обойти правило аутентификации, ограничивающее доступ к определённой конечной точке API, и получить доступ с правами администратора. Cisco оценивает уязвимость как CVSS 3.1 9,8 Critical, сообщает, что продукт затронут независимо от конфигурации, и указывает, что PSIRT узнала об активной эксплуатации в сентябре 2026 года. В бюллетене приведён URI-кодированный запрос к j_security_check как пример IOC и особо отмечено, что можно использовать любой один закодированный символ; не считайте этот пример полной сигнатурой обнаружения. Cisco не публикует уязвимый исходный код или diff исправления, поэтому приведённая ниже пара кода иллюстрирует проектирование авторизации и не является кодом Cisco или воспроизведением. Cisco перечисляет исправленные выпуски по веткам и указывает, что полноценного обходного решения нет. Сетевые ограничения и Live Protect — временные меры; щит может мешать легитимному входу и не заменяет обновление.[1], [5]

Исправленные версии CVE-2026-76504 по типу развёртывания

Развёртывание / веткаИсправленная версияДействие
Локальные версии до 20.9Перейдите на поддерживаемую ветку с опубликованной исправленной версией.Выполните миграцию; не оставайтесь на старой неподдерживаемой ветке.
Локальная ветка 20.920.9.10.1Обновите каждый менеджер до этой или более поздней версии поддерживаемой ветки.
Локальная ветка 20.1220.12.8.2Обновите каждый менеджер до этой или более поздней версии поддерживаемой ветки.
Локальная ветка 20.1520.15.6.1Обновите каждый менеджер до этой или более поздней версии поддерживаемой ветки.
Локальная ветка 20.1820.18.4.1Обновите каждый менеджер до этой или более поздней версии поддерживаемой ветки.
Локальная ветка 26.126.1.2.1Обновите каждый менеджер до этой или более поздней версии поддерживаемой ветки.
Локальная ветка 26.226.2.1Обновите каждый менеджер до этой или более поздней версии поддерживаемой ветки.
Cisco SD-WAN Cloud (Cisco Managed)20.15.605 или новее; Cisco сообщает, что облачный сервис исправлен.Убедитесь, что используется управляемый сервис; для его обновления действия клиента не требуются.

Пошаговый сценарий атаки

Шаг 1

Удалённый запрос достигает API менеджера

Учётная запись и действия пользователя не требуются. Доступ из интернета повышает риск; поставщик указывает, что конфигурация не влияет на наличие уязвимости.[1]

Шаг 2

URI-кодированный путь обходит правило аутентификации

Cisco указывает на непоследовательную обработку URI-кодирования при аутентификации API-сессии. Публичные данные не раскрывают уязвимую реализацию.[1]

Шаг 3

API обрабатывает запрос как запрос администратора

Успешная эксплуатация предоставляет права администратора. Cisco подтверждает активную эксплуатацию, но не публикует полную цепочку после доступа.[1], [5]

Шаг 4

Обновите систему и расследуйте инцидент

Соберите файлы admin-tech, обновите все менеджеры до подходящего исправленного выпуска, затем попросите Cisco TAC проверить данные. Не ждите ответа TAC перед обновлением.[1], [2]

Исходный код: Уязвимый vs Защищённый вариант

Cisco не публикует уязвимый исходный код или diff исправления. Этот пример Python показывает общий принцип проектирования, а не код Cisco: маршрутизация и авторизация должны использовать одну проверенную каноническую цель запроса, а защищённые конечные точки должны требовать подтверждённую личность. Используйте документированную нормализацию маршрутизатора/framework; не добавляйте самодельное или повторное декодирование путей. Поддерживаемое исправление CVE-2026-76504 — обновление до указанного Cisco выпуска своей ветки.[1], [7]

Фрагмент исходного кода: Иллюстративный пример на Python канонизации URI и границы авторизации; не код Cisco

УЯЗВИМАЯ РЕАЛИЗАЦИЯ
from urllib.parse import unquote, urlsplit


def dispatch(raw_target, session, routes):
    # Один уровень проверяет ещё закодированный путь.
    path_for_auth = urlsplit(raw_target).path
    if path_for_auth.startswith("/api/") and session is None:
        raise PermissionError("authentication required")

    # Следующий уровень декодирует путь перед поиском маршрута. Эти решения могут не совпасть.
    route_path = unquote(path_for_auth)
    return routes[route_path]()
БЕЗОПАСНЫЙ ИСПРАВЛЕННЫЙ ВАРИАНТ
import re
from urllib.parse import unquote, urlsplit


def canonical_path(raw_target):
    raw_path = urlsplit(raw_target).path
    if re.search(r"%(?![0-9A-Fa-f]{2})", raw_path):
        raise ValueError("malformed URI encoding")

    path = unquote(raw_path, errors="strict")
    if "%" in path or "\\" in path:
        raise ValueError("ambiguous path encoding")
    if any(part in {".", ".."} for part in path.split("/")):
        raise ValueError("path traversal segment")
    return path


def dispatch(raw_target, session, routes):
    path = canonical_path(raw_target)  # Decode and validate exactly once.
    route = routes.get(path)
    if route is None:
        raise LookupError("route not found")

    requires_authentication, handler = route
    if requires_authentication and session is None:
        raise PermissionError("authentication required")
    return handler()

Чек-лист по защите системы для инженеров

Источники