สรุปสั้น

Active Storage คือ ส่วนของเฟรมเวิร์ก Ruby on Rails ที่จัดการไฟล์อัปโหลด เช่น รูปโปรไฟล์หรือเอกสารแนบ และส่งรูปไปให้ไลบรารีภายนอกอย่าง ImageMagick หรือ libvips วิเคราะห์ เมื่อกรกฎาคม 2569 Rails เพิ่งแก้ช่องโหว่วิกฤต CVE-2026-66066 ที่กระทบแอปที่ใช้ libvips (2026/07/301 ) ล่าสุดเมื่อวันที่ 4 พฤศจิกายน 2569 Rails เปิดเผยช่องโหว่ใหม่ GHSA-f3w6-w445-fwh9 (CVSS 9.8) ที่กระทบฝั่งแอปที่ใช้ ImageMagick แทน ผู้โจมตีที่ไม่ต้องล็อกอินสามารถเขียนไฟล์ใดก็ได้บนเซิร์ฟเวอร์ด้วยการอัปโหลดไฟล์ที่ประดิษฐ์ขึ้น และถ้าแอปเก็บไฟล์ด้วย Disk service ผู้โจมตีอ่านไฟล์ที่แอปอ่านได้ทั้งหมดด้วย กลไก คือ ไฟล์ SVG ที่อัปโหลดถูกส่งไปถึงตัวจัดการรูปแบบ MSL ของ ImageMagick ซึ่งอ่านและเขียนไฟล์ตามที่สคริปต์สั่ง แค่แนบไฟล์ก็เพียงพอ แอปไม่ต้องสร้างรูปย่อหรือพรีวิว

แอปจะเสี่ยงเมื่อเข้าเงื่อนไขครบ 3 ข้อ คือ ใช้ ImageMagick ผ่าน mini_magick ใช้นโยบายความปลอดภัยของ ImageMagick ที่ไม่บล็อกตัวจัดการเหล่านี้ (ซึ่งนโยบายที่มากับ Debian และ Ubuntu ไม่บล็อก) และรับไฟล์อัปโหลดจากผู้ใช้ที่ไม่น่าเชื่อถือ ไฟล์ที่อ่านได้มักมี secret_key_base และ credential ของระบบอื่น ซึ่งต่อยอดเป็นการรันโค้ดจากระยะไกลหรือการขยายไปยังระบบอื่นได้ Rails แก้แล้วใน 8.1.4.1 และ 8.0.5.2 ซึ่งแก้ปัญหาความปลอดภัยรวม 21 รายการ นักพัฒนาควรอัปเกรดทันที และเปลี่ยนความลับทั้งหมดถ้าแอปใช้ Disk service

รายละเอียดข่าว

เว็บไซต์ The Hacker News รายงานเมื่อวันที่ 4 พฤศจิกายน 2569 ว่า Rails ประกาศช่องโหว่ผ่าน GitHub Security Advisory และยังไม่มีหมายเลข CVE ผู้รายงาน คือ นักวิจัยที่ใช้ชื่อ RyotaK จากบริษัท GMO Flatt Security ผ่าน HackerOne Rails ระบุว่าได้รับรายงานห่วงโซ่การโจมตีหนึ่งแบบ แต่ “ไม่ได้ถือว่าเป็นแบบเดียวที่มีอยู่” ประกาศไม่ได้บอกว่าช่องโหว่ถูกโจมตีจริงแล้วหรือไม่ และไม่ได้อธิบายวิธีตรวจว่าแอปเคยตกเป็นเป้าหรือยัง

ทุกเวอร์ชันของ Active Storage ก่อน 8.0.5.2 ได้รับผล รวมถึง 8.1 ก่อน 8.1.4.1 ส่วนรุ่นที่เก่ากว่า 8.0 หมดการสนับสนุนแล้วและจะไม่ได้รับเวอร์ชันแก้ไข Rails 8.0 เองจะได้รับแพตช์ความปลอดภัยถึงวันที่ 7 พฤศจิกายน 2569 เท่านั้นตามนโยบายการดูแล รีลีสเดียวกันยังแก้ช่องโหว่ที่สอง GHSA-v924-7rp8-4mxh (CVSS 8.8) ซึ่ง Active Storage ส่งไฟล์ให้ ImageMagick และ FFmpeg ด้วยชื่อไฟล์ชั่วคราวที่ยังคงนามสกุลตามที่ผู้อัปโหลดตั้ง

รายละเอียดช่องโหว่

ImageMagick เลือกตัวจัดการจากเนื้อไฟล์ ไม่ใช่จากที่แอปคาด — ImageMagick เลือกตัวจัดการรูปแบบไฟล์ที่เรียกว่า coder จากเนื้อหาของไฟล์ coder บางตัวไม่ได้ทำงานกับรูปภาพ แต่ไปทำงานกับไฟล์อื่นที่ถูกอ้างชื่อในไฟล์นั้น Active Storage ไม่ได้จำกัดว่าไฟล์อัปโหลดใช้ coder ตัวไหนได้ นโยบายความปลอดภัยของ ImageMagick บนเซิร์ฟเวอร์จึงเป็นด่านเดียว

แค่แนบไฟล์ก็ถึงจุดที่มีช่องโหว่ — ตัววิเคราะห์ ImageMagick ใน Active Storage ทำงานทันทีที่ไฟล์ถูกแนบ เพื่อดึงข้อมูลอย่างขนาดรูป แอปไม่ต้องสร้าง variant หรือ preview และไม่ต้องเรียก analyze เอง ตาม commit ที่แก้ไข ไฟล์ SVG ที่อัปโหลดเข้าถึง coder ชื่อ MSL ผ่านตัววิเคราะห์นี้ MSL คือ coder แบบสคริปต์ที่อ่านและเขียนไฟล์ตามชื่อที่สคริปต์ระบุ ผู้โจมตีจึงใช้ไฟล์ SVG ที่ฝังสคริปต์ MSL เพื่อเขียนไฟล์บนเซิร์ฟเวอร์

เงื่อนไขที่ทำให้แอปเสี่ยง — ข้อแรก แอปตั้ง config.active_storage.variant_processor เป็น :mini_magick ซึ่งเป็นค่าเริ่มต้นของแอปที่ load_defaults เป็น 6.1 หรือเก่ากว่า ถ้าไม่ได้ตั้งค่านี้ แอปที่ load_defaults ตั้งแต่ 7.0 จะใช้ :vips ค่านี้ยังกำหนดไลบรารีที่ใช้วิเคราะห์ไฟล์อัปโหลดด้วย ข้อสอง นโยบาย ImageMagick ของเซิร์ฟเวอร์ไม่บล็อก coder ที่เกี่ยวข้อง และข้อสาม แอปรับไฟล์จากผู้ใช้ที่ไม่น่าเชื่อถือ

ถ้าใช้ Disk service ผลจะร้ายแรงขึ้น — แอปที่เก็บไฟล์บนดิสก์ของเซิร์ฟเวอร์ด้วย Disk service จะถูกอ่านไฟล์ใดก็ได้ที่แอปอ่านได้ ไฟล์เหล่านี้มักรวม secret_key_base ซึ่งใช้เซ็นคุกกี้และ token และ credential ของฐานข้อมูลหรือบริการภายนอก ผู้โจมตีที่ได้ secret_key_base อาจปลอม session หรือสร้าง payload ที่ทำให้รันโค้ดได้

ช่องโหว่ที่สอง: นามสกุลไฟล์เลือกตัวถอดรหัส — ใน GHSA-v924-7rp8-4mxh ImageMagick และ FFmpeg เลือกตัวถอดรหัสจากนามสกุลเมื่อเนื้อไฟล์ไม่ได้บอกรูปแบบ ผู้โจมตีที่ตั้งชื่อไฟล์และประกาศ content type เองจึงเลือกตัวถอดรหัสที่จะประมวลผลไฟล์นั้นได้

ผลกระทบ

กลุ่มที่เสี่ยง คือ แอป Rails ที่ใช้ ImageMagick ผ่าน mini_magick และเปิดให้ผู้ใช้ทั่วไปอัปโหลดรูป เช่น เว็บที่ให้สมัครสมาชิกแล้วตั้งรูปโปรไฟล์ แอปที่เริ่มต้นจาก Rails 6.1 หรือเก่ากว่าแล้วอัปเกรดมาโดยไม่ได้เปลี่ยนค่า load_defaults มีโอกาสใช้ ImageMagick โดยไม่รู้ตัว ส่วนเซิร์ฟเวอร์ Debian และ Ubuntu ไม่ได้บล็อก coder อันตรายในนโยบายเริ่มต้น จึงไม่มีด่านกันชั้นที่สอง

ผลลัพธ์เมื่อโดนมี 2 ระดับ ระดับแรก คือ ผู้โจมตีเขียนไฟล์บนเซิร์ฟเวอร์ได้ ซึ่งอาจใช้วางเว็บเชลล์หรือแก้ไฟล์ของแอป ระดับที่สอง สำหรับแอปที่ใช้ Disk service คือ ความลับทั้งหมดของแอปหลุด ซึ่งพาไปสู่ฐานข้อมูล storage และบริการภายนอกที่แอปเชื่อมต่อ ความเร่งด่วนสูงเพราะไม่ต้องล็อกอิน และ Rails ยอมรับว่าอาจมีห่วงโซ่การโจมตีแบบอื่นอีก

คำแนะนำ

  • ทำทันที: อัปเกรดเป็น Rails 8.1.4.1 หรือ 8.0.5.2 และถ้าใช้ :mini_magick ต้องใช้ gem mini_magick 5.1 ขึ้นไป ไม่อย่างนั้นแอปจะ error ตอนบูต
  • ทำทันที (ยังอัปเกรดไม่ได้): คัดลอกกฎจาก activestorage/lib/active_storage/image_magick/policy.xml ไปใส่ในนโยบายระบบของ ImageMagick เช่น /etc/ImageMagick-7/policy.xml อย่างน้อยต้องบล็อก coder MSL, coder ที่ใช้ Ghostscript และ gs delegate แอปที่เก่ากว่า 8.0 ใช้วิธีนี้หรืออัปเกรดเป็น 8.0 ขึ้นไป
  • ตรวจว่านโยบายใหม่ทำงานจริง: รัน bin/rails runner 'puts MiniMagick.identify { |i| i.list "policy" }' และตรวจว่าแอปไม่ได้แทนที่ MiniMagick.cli_env ล้าง environment ด้วย MiniMagick.cli_prefix หรือติดตั้ง MiniMagick::Shell ของตัวเอง ซึ่งจะทำให้นโยบายที่ให้มาไม่มีผล
  • ตรวจนโยบายบนเซิร์ฟเวอร์: หากฎที่อนุญาต coder แบบกว้าง เช่น pattern="*" ใน policy.xml ของระบบ เพราะจะทับการบล็อกของนโยบายใหม่ ส่วนแอปที่ใช้ GraphicsMagick จะไม่ได้รับการป้องกันจากนโยบายนี้เลย
  • ถ้าแอปใช้ Disk service: เปลี่ยน secret_key_base, master key, ทุกค่าใน config/credentials.yml.enc, credential ของ storage และฐานข้อมูล และ token ของบุคคลที่สาม และอย่าเก็บค่าเก่าไว้เป็น fallback
  • ถ้าต้องเรนเดอร์ PDF หรือ PostScript: อนุญาต gs delegate และ coder ที่จำเป็นกลับใน policy.xml ของเซิร์ฟเวอร์อย่างระมัดระวัง และจำกัดเฉพาะงานที่ไม่รับไฟล์จากผู้ใช้ทั่วไป

แหล่งอ้างอิง