Đây là hai tính năng SSRF điển hình: server tự đi gọi một URL do user kiểm soát, và server đứng bên trong mạng nội bộ.
Mục tiêu kẻ tấn công nhắm tới: http://169.254.169.254/ (metadata của cloud, lấy được IAM credential), http://localhost:port (admin panel, Redis, Elasticsearch không auth), dải nội bộ 10.x, 172.16-31.x, 192.168.x, và các scheme lạ file://, gopher://, dict://.
Thiết kế phòng thủ theo lớp:
1. Allowlist scheme và port: chỉ http/https, chỉ 80/443. Từ chối mọi thứ khác ngay.
2. Resolve DNS trước, rồi kiểm tra IP — không kiểm tra hostname bằng chuỗi. Chặn loopback, link-local, private, multicast, IPv6 ::1/fc00::/7 và cả IPv4-mapped IPv6.
3. Chống DNS rebinding: khoảng giữa lúc kiểm tra và lúc gọi, DNS có thể đổi sang IP nội bộ. Cách chắc chắn là resolve một lần rồi kết nối thẳng tới IP đã kiểm tra (đặt Host header thủ công), hoặc dùng thư viện HTTP có hook kiểm tra socket trước khi connect.
4. Không tự động follow redirect, hoặc follow thủ công và kiểm tra lại IP ở mỗi hop — chuyển hướng 302 sang 169.254.169.254 là bypass phổ biến nhất.
5. Giới hạn tài nguyên: timeout, kích thước tải tối đa, và kiểm tra Content-Type thực tế của phản hồi.
6. Chặn ở tầng hạ tầng: cho worker gọi ra ngoài qua egress proxy trong subnet riêng, chặn dải nội bộ bằng security group. Đây là lớp cứu bạn khi code có sót.
7. Với cloud, bật IMDSv2 để metadata endpoint yêu cầu token, không lấy được bằng một GET đơn thuần.
Cuối cùng: thông báo lỗi trả về phải chung chung. Trả nguyên body hay status code của request nội bộ sẽ biến SSRF mù thành SSRF đọc được dữ liệu.