☕ 5-Min Tech Story #42

SSRF: แค่ฟีเจอร์ "ดึงรูปโปรไฟล์จาก URL" ทำไมแฮกเกอร์ถึงแอบสูบกุญแจลับ AWS ไปได้หมดทั้งคลาวด์?

⏱️ ใช้เวลาอ่านประมาณ: 4 นาที 30 วินาที

คุณทำฟีเจอร์เอาใจผู้ใช้งาน: "เปลี่ยนรูปโปรไฟล์ได้ง่ายๆ แค่แปะ URL ลิงก์รูปภาพจากอินเทอร์เน็ต แล้วให้ Backend แอบดาวน์โหลดมาเก็บไว้ใน S3 ให้"

โค้ดสั้นๆ แค่ 2 บรรทัดทำงานได้อย่างราบรื่น:

// รับ URL มาจาก Client แล้วยิงดาวน์โหลดตรงๆ
val imageBytes = httpClient.get(userProvidedUrl).bodyAsBytes()
s3Client.upload(imageBytes)

จนกระทั่งบ่ายวันหนึ่ง มีแฮกเกอร์คนหนึ่งไม่ได้ส่ง URL รูปแมวเข้ามา... แต่เขาส่งที่อยู่ปริศนานี้เข้ามาแทน:

http://169.254.169.254/latest/meta-data/iam/security-credentials/app-role

และในเสี้ยววินาทีต่อมา เซิร์ฟเวอร์ของคุณก็ตอบกลับพร้อม AccessKeyId, SecretAccessKey และ SessionToken ของระบบ AWS ส่งตรงถึงมือแฮกเกอร์อย่างสุภาพ! เกิดอะไรขึ้น?

🕵️ ยืมมือฆ่าคน: ช่องโหว่ SSRF (Server-Side Request Forgery)

ตามปกติ บริษัทจะสร้าง Firewall กั้นไว้อย่างแน่นหนา แฮกเกอร์จากอินเทอร์เน็ตภายนอกไม่มีวันยิงเข้าหา IP วงใน (Internal Network / Intranet) ได้โดยตรง

แต่ช่องโหว่ SSRF คือการที่แฮกเกอร์ไม่ได้ยิงเอง แต่ "สั่งให้เซิร์ฟเวอร์ของคุณ (ซึ่งนั่งอยู่หลัง Firewall) เป็นคนยิง Request แทน!"

"เหมือนยามหน้าประตูที่ซื่อสัตย์... ถ้าคนแปลกหน้าจะเดินเข้าตึก ยามจะสกัดไว้ แต่ถ้าพนักงานในตึก (เซิร์ฟเวอร์ของเรา) เดินไปหยิบของข้างในมาให้ ยามจะปล่อยผ่าน 100%!"

☁️ เลขอาถรรพ์ 169.254.169.254 คืออะไร?

บนระบบคลาวด์ยอดนิยม เช่น AWS EC2, Google Cloud, Azure หรือ DigitalOcean จะมีที่อยู่ IP วิเศษ (Link-local address) ตัวหนึ่งเหมือนกันหมดคือ 169.254.169.254 เรียกว่า Instance Metadata Service (IMDS)

💥 คดีประวัติศาสตร์: Capital One Data Breach (2019)

หนึ่งในการโจรกรรมข้อมูลที่โด่งดังที่สุดในโลกของธนาคาร Capital One ซึ่งทำให้ข้อมูลลูกค้ากว่า 100 ล้านคน ถูกขโมย เกิดขึ้นจากช่องโหว่ SSRF ใน Web Application Firewall (WAF) ตัวหนึ่ง

แฮกเกอร์สั่งให้ WAF ตัวนั้นยิงไปดึงสิทธิ์จาก 169.254.169.254 แล้วเอากุญแจ IAM Role ที่ได้ไปสั่งดาวน์โหลดข้อมูลบัตรเครดิตทั้งหมดออกจากถัง AWS S3 Bucket กวาดไปจนเกลี้ยง!

🛡️ 2 คาถาป้องกัน SSRF: ดัดหลัง URL และล็อกตาย IMDSv2

1. บังคับย้ายไปใช้ AWS IMDSv2 (Session-oriented Token):

AWS ออกมาตรฐาน IMDSv2 มาเพื่อปราบ SSRF โดยเฉพาะ: การจะขอ Metadata ได้ ต้องส่งคำสั่ง PUT พร้อม Header พิเศษไปขอบัตรคิวก่อน ถึงจะเอาไป GET ได้ ซึ่งฟังก์ชันดาวน์โหลดรูปทั่วไปมักยิงได้แค่ GET ธรรมดา จึงเจาะไม่เข้าอีกต่อไป

# บังคับเปิดใช้ IMDSv2 บน EC2 (ปิดการเข้าถึงแบบ v1 ทันที)
aws ec2 modify-instance-metadata-options \
  --instance-id i-1234567890abcdef0 \
  --http-tokens required \
  --http-endpoint enabled

2. ตรวจสอบ IP ปลายทางก่อนยิง (Egress IP Filtering):

ห้ามเชื่อใจ URL ที่ผู้ใช้ส่งมาเด็ดขาด! ก่อนจะสั่งให้ HTTP Client ดาวน์โหลดของ ต้องทำการ Resolve DNS ออกมาเป็น IP ก่อนเสมอ:

💡 5-Min Takeaway

"เมื่อใดก็ตามที่เซิร์ฟเวอร์ของคุณต้องยิง Request ออกไปตามคำสั่งของผู้ใช้ นั่นคือจุดเสี่ยงสูงสุดของระบบ" อย่ามองแค่ความถูกต้องของข้อมูลภายนอก แต่ต้องระวังไม่ให้เซิร์ฟเวอร์กลายเป็นสะพานเชื่อมให้ผู้ไม่หวังดีเข้ามาสำรวจเครือข่ายภายใน จงปิดการใช้งาน IMDSv1 บนคลาวด์ทุกเครื่องตั้งแต่วันนี้ และกรอง Private IP ทุกครั้งก่อนส่งคำขอดาวน์โหลด เพื่อไม่ให้กุญแจบ้านของคุณหลุดไปอยู่ในมือของคนอื่น