1 คะแนน โดย GN⁺ 2025-03-16 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • CVE-2025-25291 และ CVE-2025-25292 ที่พบใน ruby-saml 1.17.0 หรือต่ำกว่า ทำให้สามารถล็อกอินเป็นผู้ใช้ใดก็ได้ด้วยลายเซ็นที่ถูกต้องเพียงหนึ่งรายการ เพิ่มความเสี่ยงการยึดบัญชีในสภาพแวดล้อม SAML SSO
  • ช่องโหว่นี้เกิดจากความแตกต่างของพาร์เซอร์ในเส้นทางการตรวจสอบลายเซ็น ซึ่ง REXML และ Nokogiri อาจตีความองค์ประกอบ Signature คนละตัวจากเอกสาร XML เดียวกัน
  • เมื่อ SignedInfo, SignatureValue, แฮชของ assertion และ DigestValue ถูกประกอบจากผลลัพธ์ของพาร์เซอร์ที่ต่างกัน การตรวจแต่ละรายการจึงผ่านได้ แต่ การเชื่อมโยงระหว่างแฮชกับลายเซ็น อาจถูกตัดขาด
  • GitHub ดำเนินการ bug bounty และรีวิวโดย Security Lab ระหว่างพิจารณานำ ruby-saml กลับมาใช้ พบอินสแตนซ์ที่โจมตีได้ใน GitLab และแจ้งทีมความปลอดภัยแล้ว ปัจจุบันการยืนยันตัวตนของ GitHub ไม่ได้ใช้ ruby-saml
  • ผู้ใช้ควรอัปเดตเป็น ruby-saml 1.18.0 และไลบรารีที่อ้างอิง ruby-saml เช่น omniauth-saml ก็ควรอัปเกรดไปยังรีลีสที่อ้างอิงเวอร์ชันที่แก้ไขแล้วด้วย

ผลกระทบของการบายพาสการยืนยันตัวตนใน ruby-saml

  • พบช่องโหว่ บายพาสการยืนยันตัวตนความรุนแรงสูง 2 รายการใน ruby-saml 1.17.0 หรือต่ำกว่า
    • CVE-2025-25291
    • CVE-2025-25292
  • หากผู้โจมตีมี ลายเซ็นที่ถูกต้องหนึ่งรายการ ซึ่งสร้างด้วยคีย์ที่ใช้ตรวจสอบ SAML response หรือ assertion ขององค์กรเป้าหมาย ก็สามารถสร้าง SAML assertion เองเพื่อล็อกอินเป็นผู้ใช้ใดก็ได้
  • แหล่งที่มาของลายเซ็นที่เป็นไปได้มีดังนี้
    • assertion หรือ response ที่ลงลายเซ็นของผู้ใช้อื่นที่มีสิทธิ์ต่ำกว่า
    • ในบางกรณี metadata ที่ลงลายเซ็นของ SAML IdP ที่เข้าถึงได้แบบสาธารณะ
  • ช่องโหว่นี้จึงอาจถูกใช้ในการโจมตีเพื่อ ยึดบัญชี ได้
  • ปัจจุบัน GitHub ไม่ได้ใช้ ruby-saml สำหรับการยืนยันตัวตน แต่ได้ประเมิน ruby-saml ระหว่างพิจารณานำไลบรารีโอเพนซอร์สกลับมาใช้สำหรับการยืนยันตัวตนแบบ SAML
  • ruby-saml ยังถูกใช้ในโปรเจกต์และผลิตภัณฑ์ยอดนิยมอื่น ๆ ด้วย และ GitHub พบอินสแตนซ์ที่โจมตีได้ใน GitLab จึงแจ้งทีมความปลอดภัยของ GitLab

เหตุผลที่ GitHub กลับมาพิจารณา ruby-saml อีกครั้ง

  • GitHub ใช้ ruby-saml จนถึงปี 2014 แต่ย้ายไปใช้การติดตั้ง SAML ของตนเองเพราะในขณะนั้นขาดฟีเจอร์ที่จำเป็น
  • หลังจากนั้น การติดตั้งของตนเองก็มีรายงาน bug bounty เช่น CVE-2024-9487 ซึ่งเป็นช่องโหว่เกี่ยวกับ assertion ที่เข้ารหัส และ GitHub เริ่มพิจารณานำ ruby-saml กลับมาใช้
  • ในเดือนตุลาคม 2024 มีการเปิดเผยช่องโหว่บายพาสการยืนยันตัวตนของ ruby-saml CVE-2024-45409 ที่ ahacker1 ค้นพบ
  • GitHub เริ่ม bug bounty แบบไม่เปิดเผยต่อสาธารณะ เพื่อประเมินความเป็นไปได้ในการย้ายไปใช้ ruby-saml อย่างละเอียดขึ้น
    • ให้สิทธิ์นักวิจัยที่ได้รับคัดเลือกเข้าถึงสภาพแวดล้อมทดสอบของ GitHub ที่ใช้ ruby-saml สำหรับการยืนยันตัวตนแบบ SAML
    • GitHub Security Lab ก็ร่วมตรวจสอบ attack surface ของ ruby-saml ด้วย

ความไม่สอดคล้องของการตรวจสอบที่เกิดจาก XML parser สองตัว

  • ระหว่างการรีวิวโค้ด ahacker1 และ GitHub Security Lab พบว่าในเส้นทางการตรวจสอบลายเซ็นของ ruby-saml มีการใช้ XML parser สองตัวร่วมกัน
    • REXML: XML parser ที่เขียนด้วย Ruby ล้วน
    • Nokogiri: รองรับการพาร์ส XML และ HTML โดยมี API ครอบ libxml2, libgumbo, Xerces สำหรับ JRuby เป็นต้น
  • เส้นทางที่เป็นปัญหาคือเมธอด validate_signature ใน xml_security.rb
  • เมธอดนี้อ่านองค์ประกอบ Signature ตัวแรกและ SignatureValue จริงด้วย REXML
    • REXML::XPath.first(@working_copy, "//ds:Signature", {"ds"=>DSIG})
  • ในขณะเดียวกัน ภายในโฟลว์การตรวจสอบเดียวกัน Signature และ SignedInfo จะถูกค้นหาและ canonicalize อีกครั้งด้วย Nokogiri
    • document.at_xpath('//ds:Signature', 'ds' => DSIG)
    • noko_signed_info_element.canonicalize(canon_algorithm)
  • assertion ถูกดึงออกมา canonicalize และแฮชด้วย Nokogiri แต่ DigestValue ที่ใช้เปรียบเทียบมาจาก REXML
  • วัสดุที่ใช้ตรวจสอบขั้นสุดท้ายจึงแยกกันดังนี้
    • assertion ถูกดึงออกมาและ canonicalize ด้วย Nokogiri แล้วนำไปแฮช
    • แฮชที่ใช้เปรียบเทียบมาจาก DigestValue ที่ REXML อ่าน
    • SignedInfo ถูกดึงออกมาและ canonicalize ด้วย Nokogiri
    • SignatureValue ถูกดึงออกมาด้วย REXML

การเชื่อมโยงด้านความปลอดภัยที่ถูกตัดขาดในการตรวจสอบลายเซ็น SAML

  • SAML response ส่งข้อมูลผู้ใช้ที่ล็อกอินจาก IdP ไปยัง SP ในรูปแบบ XML
  • เมื่อใช้ HTTP POST binding SAML response จะถูกส่งผ่านเบราว์เซอร์ของผู้ใช้ไปยัง SP จึงจำเป็นต้องมี การตรวจสอบลายเซ็น เพื่อป้องกันไม่ให้ผู้ใช้แก้ไขข้อความ
  • ใน SAML response แบบย่อ ข้อมูลสำคัญมักอยู่ใน Subject และ NameID ภายใน Assertion
  • โดยทั่วไป อาจลงลายเซ็นที่ assertion หรือ SAML response ทั้งหมดก็ได้
  • เมื่อ assertion ถูกลงลายเซ็น การตรวจสอบจะดำเนินการสองขั้นตอน
    • ลบ Signature ออกจาก assertion แล้ว canonicalize และแฮชเพื่อเปรียบเทียบกับ DigestValue
    • canonicalize SignedInfo แล้วตรวจสอบลายเซ็นด้วย SignatureValue
  • ในช่องโหว่นี้ แม้ทั้งสองขั้นตอนจะผ่าน แต่ก็ไม่สามารถรับประกันได้ว่าเป็นข้อมูลชุดเดียวกัน
    • แฮชอาจเป็นแฮชของ assertion จริง
    • ลายเซ็นอาจเป็นลายเซ็นขององค์ประกอบ SignedInfo อื่น
  • คุณสมบัติด้านความปลอดภัยที่จำเป็นคือเนื้อหาที่ถูกแฮช แฮช และลายเซ็นต้องเชื่อมโยงกันโดยตรง และหลังการตรวจสอบควรอ่านข้อมูลจากส่วนที่ได้รับการตรวจสอบจริงเท่านั้น

วิธีประกอบ exploit จริง

  • เงื่อนไขสำคัญคือการทำให้ REXML และ Nokogiri มองเห็น Signature คนละตัว ในเอกสาร XML เดียวกัน และในทางปฏิบัติทำได้จริง
  • ahacker1 สร้าง exploit ที่ทำงานได้โดยใช้ความแตกต่างของพาร์เซอร์เป็นคนแรกระหว่างเข้าร่วม bug bounty
    • ได้แรงบันดาลใจจาก XML roundtrips vulnerabilities ที่ Juho Forsén จาก Mattermost เปิดเผยในปี 2021
  • GitHub Security Lab ใช้ Ruby fuzzer ruzzy ของ Trail of Bits เพื่อสร้าง exploit อีกแบบที่อิงความแตกต่างของพาร์เซอร์
  • exploit ตัวอย่างใส่ Signature เพิ่มเติมที่มีเพียง Nokogiri เท่านั้นที่มองเห็นไว้ภายในองค์ประกอบ StatusDetail
  • โฟลว์การตรวจสอบจึงถูกแยกดังนี้
    • SignedInfo ของ signature ที่ Nokogiri มองเห็นถูก canonicalize
    • ตรวจสอบด้วย SignatureValue ที่ดึงจาก signature ที่ REXML มองเห็น
    • assertion ที่ Nokogiri ค้นหาด้วย ID ถูก canonicalize และแฮช
    • แฮชถูกเปรียบเทียบกับ DigestValue ที่ REXML อ่าน
  • ท้ายที่สุด SignedInfo ที่ถูกต้องกับลายเซ็นที่ถูกต้องสอดคล้องกัน และ assertion ที่ถูกแก้ไขกับ digest ที่คำนวณจากมันก็สอดคล้องกัน ทำให้ ruby-saml ยอมรับ assertion

มาตรการบรรเทาและข้อจำกัดในการตรวจจับ

  • หากตรวจสอบ ข้อผิดพลาดในการพาร์ส เมื่อพาร์ส SAML response ด้วย Nokogiri จะสามารถกัน exploit แบบไม่เปิดเผยต่อสาธารณะบางรายการที่ทราบอยู่ในปัจจุบันได้
  • ข้อผิดพลาดในการพาร์สของ Nokogiri ไม่ได้เกิดเป็น exception จึงต้องตรวจสอบสมาชิก errors ของเอกสารที่พาร์สแล้วโดยตรง
  • โค้ดตัวอย่างใช้ตัวเลือก Nokogiri::XML::ParseOptions::STRICT | Nokogiri::XML::ParseOptions::NONET และทำให้เกิดข้อผิดพลาดเมื่อ doc.errors.any?
  • วิธีนี้ไม่ใช่การแก้ไขที่สมบูรณ์ แต่ทำให้ exploit อย่างน้อยหนึ่งรายการไม่สามารถรันได้
  • ยังไม่มี ตัวบ่งชี้การบุกรุก ที่เชื่อถือได้
    • ตัวบ่งชี้ที่เป็นไปได้หนึ่งรายการทำงานได้เฉพาะในสภาพแวดล้อมคล้าย debug เท่านั้น
    • หากเปิดเผยตัวบ่งชี้นั้นจะเผยรายละเอียดการทำงานของ exploit ที่ใช้ได้มากเกินไป จึงไม่เปิดเผย
  • วิธีตรวจสอบที่แนะนำคือค้นหาการล็อกอิน SAML ที่น่าสงสัยในฝั่ง SP เช่น การล็อกอินจากที่อยู่ IP ที่ไม่ตรงกับตำแหน่งที่คาดไว้ของผู้ใช้

แนวทางแก้ไขและเป้าหมายการอัปเดต

  • การแก้ไขเริ่มต้นไม่ได้ตัด XML parser ตัวใดตัวหนึ่งออก เนื่องจากมีปัญหาความเข้ากันได้ของ API
  • ปัญหาที่เป็นรากฐานมากกว่าคือ การแยกการตรวจสอบแฮชออกจากการตรวจสอบลายเซ็น และการแยกนี้ถูกใช้โจมตีได้ผ่านความแตกต่างของพาร์เซอร์
  • งานตัด XML parser ตัวใดตัวหนึ่งออกมีการวางแผนไว้แล้วด้วยเหตุผลอื่น และอาจเกิดขึ้นในรีลีสหลักพร้อมการปรับปรุงเพิ่มเติม
  • ผู้ใช้ ruby-saml ควรอัปเดตเป็น 1.18.0 ซึ่งมีการแก้ไขแล้ว
  • ควรตรวจสอบไลบรารีที่ใช้ ruby-saml ร่วมด้วย
    • เช่น omniauth-saml
    • ไลบรารีดังกล่าวควรถูกอัปเดตเป็นเวอร์ชันที่อ้างอิง ruby-saml เวอร์ชันที่แก้ไขแล้ว
  • GitHub Security Lab มีแผนจะเผยแพร่ proof-of-concept exploit ในอนาคตที่ GitHub Security Lab repository

กำหนดการเปิดเผยและการรับมือ

  • 2024-11-04: ได้รับรายงาน bug bounty ที่พิสูจน์การบายพาสการยืนยันตัวตนในสภาพแวดล้อมทดสอบของ GitHub ซึ่งกำลังประเมินการยืนยันตัวตน SAML ด้วย ruby-saml
  • 2024-11-04: เริ่มระบุและทดสอบมาตรการบรรเทาที่เป็นไปได้
  • 2024-11-12: พบการบายพาสการยืนยันตัวตนครั้งที่สองที่ทำให้แผนบรรเทาแรกใช้ไม่ได้
  • 2024-11-13: ติดต่อ Sixto Martín ผู้ดูแล ruby-saml เป็นครั้งแรก
  • 2024-11-14: รายงานความแตกต่างของพาร์เซอร์สองกรณีต่อ ruby-saml และผู้ดูแลตอบกลับทันที
  • 2024-11-14: ผู้ดูแลและ ahacker1 เริ่มทำงานกับแพตช์ที่เป็นไปได้
    • หนึ่งในไอเดียแรกคือการตัด XML parser ตัวใดตัวหนึ่งออก แต่ไม่สามารถทำได้โดยไม่ทำลายความเข้ากันได้ย้อนหลัง
  • 2025-02-04: ahacker1 เสนอแนวทางแก้ไขที่ไม่เข้ากันได้ย้อนหลัง
  • 2025-02-06: ahacker1 เสนอแนวทางแก้ไขที่เข้ากันได้ย้อนหลังด้วย
  • 2025-02-12: ครบกำหนด 90 วันของ advisory จาก GitHub Security Lab
  • 2025-02-16: ผู้ดูแลเริ่มทำงานในแนวทางแก้ไขที่รักษาความเข้ากันได้ย้อนหลังและเข้าใจง่าย
  • 2025-02-17: ติดต่อ GitLab เป็นครั้งแรกเพื่อประสานงานรีลีสของ ruby-saml และรีลีสผลิตภัณฑ์ on-premises ของ GitLab
  • 2025-03-12: รีลีส ruby-saml เวอร์ชันที่แก้ไขแล้ว

1 ความคิดเห็น

 
GN⁺ 2025-03-16
ความคิดเห็นบน Hacker News
  • ผมมองว่าการใช้งาน SAML ของ GitHub แทบไม่มีประโยชน์
    เจตนาเดิมคือให้นำบัญชีส่วนตัวมาใช้กับองค์กรได้ ซึ่งในไซต์ GitHub เองก็ทำงานได้ในระดับหนึ่ง แต่เมื่อแอปที่ล็อกอินผ่าน GitHub ได้รับอนุมัติในระดับองค์กรแล้ว ก็ไม่สามารถป้องกันไม่ให้แอปอ่านสถานะสมาชิกขององค์กรได้
    เซสชัน SAML จำเป็นเฉพาะตอนที่แอปนั้นดึงข้อมูลด้วยโทเค็นที่ได้จากผู้ใช้คนนั้นเท่านั้น แต่ในทางปฏิบัติ เครื่องมือ SAST แทบทั้งหมดใช้โทเค็นอินสแตนซ์ของแอป และแค่มีบัญชี GitHub อยู่ในองค์กรก็แสดงโค้ดให้ดูแล้ว
    Tailscale แก้ไขหลังจากได้รับแจ้ง, Sonarcloud ขอว่าอย่าบอกใคร ส่วน GitHub ตอบหลังผ่านไปไม่กี่สัปดาห์ว่า “เป็นพฤติกรรมที่คาดไว้ทั้งหมด” แต่ไม่มีผู้ให้บริการรายไหนที่ผมแจ้งเข้าใจแบบนั้น และเอกสารก็ขัดแย้งกับคำตอบของ GitHub
    การรายงานบั๊กด้านความปลอดภัย แม้จะบังเอิญเจอก็ไม่ได้ให้ความรู้สึกคุ้มค่า และยากจะจินตนาการว่าทำสิ่งนี้เป็นอาชีพ

    • วิธี “นำบัญชีส่วนตัวมาใช้กับองค์กร” สร้างปัญหาที่เกินกว่าเรื่องการอนุญาตสิทธิ์ด้วย
      บางครั้ง GitHub เคยตั้งค่าเริ่มต้นเป็น ที่อยู่อีเมลส่วนตัว ตอน merge PR งาน ดังนั้นถ้ามีใครถาม ผมจะแนะนำว่าไม่ควรเอาบัญชีส่วนตัวกับบัญชีงานไปปนกันในบัญชีเดียว ไม่ว่าจะบน GitHub หรือที่ไหนก็ตาม
    • ก็พอเข้าใจฝั่งผู้ให้บริการอยู่บ้าง เพราะ GitHub ทำให้การ implement เรื่องนี้ให้ถูกต้องเป็นเรื่องยากสุด ๆ
      ตอนทำ https://dev.log.xyz ซึ่งเป็นเครื่องมือวิเคราะห์ repository/commit/PR ต้องใช้ความพยายามมากเพื่อให้ตรงกับหลักว่า “สิ่งที่เห็นได้บน GitHub เท่านั้น จึงจะเห็นได้บน Devlog” และประสบการณ์ทั้งหมดน่าหงุดหงิดมาก
      ตัวเลือกสิทธิ์ OAuth ของ GitHub ก็สับสนเกินไป ทำให้ยากจะมั่นใจว่าเวลาทำ “ล็อกอินด้วย GitHub” กำลังแชร์ข้อมูลใดขององค์กรใดอยู่กันแน่
    • รูปแบบการดำเนินงานแบบนี้เกิดซ้ำในทุกระดับ
      แม้แต่การโน้มน้าวนักพัฒนารุ่นใหม่ที่คุ้นกับ JavaScript ว่าแค่ การตรวจสอบฝั่งไคลเอนต์ นั้นไม่พอก็ยังยาก และยิ่งยากกว่านั้นเมื่อเป็นผู้ประกอบธุรกิจที่กำหนด requirement ของฟีเจอร์กับงบประมาณ
    • สมมติฐานที่ว่าความสะดวกจาก credential ที่ใช้ร่วมกันและ SSO จะช่วยเพิ่มความปลอดภัย ถูกช่องโหว่แบบนี้เพียงช่องเดียวทำลายลง
      ที่เก็บรหัสผ่านในรูปแบบใดก็ตาม แม้กระทั่งที่เก็บแบบกายภาพหรือแม้แต่การใช้รหัสผ่านซ้ำ สุดท้ายอาจปลอดภัยกว่าด้วยซ้ำ
      ท้ายที่สุด มินิมัลลิสม์ ก็ชนะอีกครั้ง
    • สำหรับคนที่พยายามเชื่อมโยงเรื่องข้างต้นกับงานวิจัยช่องโหว่นี้ เรื่องนี้ดูไม่น่าเกี่ยวกัน
      มีข้อความว่า “GitHub doesn’t currently use ruby-saml for authentication, but began evaluating the use of the library with the intention of using an open source library for SAML authentication once more”
  • เพิ่งต้อง implement SAML เมื่อไม่นานมานี้ และชื่อเรื่องนี้ไม่ทำให้แปลกใจเลย
    สเปก SAML เองค่อนข้างสมเหตุสมผล แต่ XML signature ที่เป็นฐานของมัน และยิ่งไปกว่านั้น XML canonicalization ถ้ายังเรียกว่าสแตนดาร์ดได้ ก็ถือว่าบ้าคลั่งจริง ๆ
    สเปกที่บิดเบี้ยวและเสื่อมเสียแบบนี้คงมีแต่คณะกรรมการเท่านั้นที่สร้างได้ และดูเหมือนว่าในหัวของคนคนเดียวคงไม่อาจยึดจับและผสมความคิดที่ขัดแย้งกันขนาดนี้ได้
    แค่ส่งลายเซ็นผ่านช่องทางนอกแบนด์ SAML ก็คงกลายเป็นสิ่งที่ implement ได้อย่างสนุกแล้ว

    • มันแย่กว่าที่พูดไปมาก
      XML ย่อมาจาก eXtensible Markup Language ตามตัวอักษร แต่คณะกรรมการมาตรฐาน SAML กลับประดิษฐ์ ภาษากลไกส่วนขยาย ของตัวเองซ้อนขึ้นไปอีกชั้น
      การเอาโปรโตคอลมาซ้อนบนโปรโตคอลเพื่อข้อมูลขนาดเล็กมากที่แทบไม่ต่างจากข้อมูลใน authentication cookie เป็นความโง่ชนิดพิเศษที่มีแต่คณะกรรมการขนาดใหญ่และเต็มไปด้วยระบบราชการที่สุดเท่านั้นจะสร้างได้
    • ไม่แน่ใจว่า SSO เองพอจะกอบกู้ได้ตั้งแต่แรกหรือเปล่า
      แนวคิดการล็อกอินแยกกันในแต่ละบัญชีก็ดูโอเคอยู่
      โครงสร้างที่เชื่อมบัญชีเข้าด้วยกันจนทำให้ถูกเจาะทีเดียวในสเกลใหญ่ได้นั้น โดยพื้นฐานแล้วอันตรายกว่า
  • ผมมองว่า SAML และในความหมายที่กว้างกว่านั้น XML-DSIG เป็นโปรโตคอลความปลอดภัยที่ใช้กันแพร่หลายซึ่งแย่ที่สุดอย่างแท้จริง
    โดยทั่วไปควรย้ายไป OAuth ไม่ว่าจะต้องจ่ายด้วยต้นทุนแค่ไหน และอย่างน้อยผมคงปฏิเสธการเอาผลิตภัณฑ์ใหม่ออกสู่ตลาดโดยพึ่งพาสิ่งนี้
    มันอันตรายมาก และถ้าไม่มี breakthrough ในการตรวจสอบรูปแบบที่ใช้งานได้จริง ก็ยากจะจินตนาการว่านี่จะเป็นช่องโหว่ DSIG ครั้งสุดท้ายหรือเป็นช่องโหว่ที่แย่ที่สุด

    • สักวันหนึ่งผมจะเขียนถึงสิ่งที่โง่อย่างไม่น่าเชื่อทั้งหมดที่ XML DSig ทำ
      ยังไม่ได้แตะเรื่องวิทยาการเข้ารหัสเลย แต่มันก็เป็นยอดสุดของวิธีคิดแบบซอฟต์แวร์องค์กรแล้ว
      ควรมีใครสักคนขุดลึกเข้าไปในความพังพินาศของ mailing list และองค์กรมาตรฐานของพวก WS-* กับ OASIS/XACML
    • น่าสนุกดีว่า Security Cryptography Whatever จะจัดการกับความโกลาหลของ SAML สัปดาห์นี้อย่างไร
    • ถ้าผมเข้าใจถูก SAML ยังมีจุดต่างอยู่ตรงที่ผู้ให้บริการ SSO สามารถยกเลิกเซสชันได้
      ใช่ไหม?
  • อื้อ ถ้าไม่ใช่กรณีที่ไม่มีทางเลือกอื่นจริง ๆ ก็ไม่มีใครควรใช้ REXML
    มันยินดี parse แม้แต่ XML ที่ผิด ทำให้เกิดปัญหาไม่รู้จบในขั้นตอนถัดไป
    มัน parse XML ด้วย regular expression อย่างแท้จริง และเป็นตัวอย่างที่ยอดเยี่ยมว่าทำไมถึงไม่ควรทำแบบนั้น
    โปรเจกต์ต่าง ๆ ไม่ได้เริ่มใช้ Nokogiri เพราะเรื่องประสิทธิภาพ แต่เพราะ ความถูกต้อง

    • นี่ไม่ใช่ตัวอย่างตามตำราเลยหรือ?
      อย่า parse สิ่งที่ไม่ใช่ regular language ด้วย regular expression
    • หนึ่งในความเสี่ยงของตัวช่วยเขียนโค้ด AI คือมันไม่ได้มองบริบทที่กว้างขึ้นของไลบรารีที่ใช้ใน codebase ขนาดใหญ่เสมอไป
      เมื่อไม่นานมานี้ผมทดสอบ o3 และทุกครั้งที่พยายามแก้ปัญหาที่ไม่เกี่ยวกับไลบรารีของบล็อกโค้ดเฉพาะ มันก็เปลี่ยนไลบรารีที่บล็อกนั้นใช้อยู่เรื่อย ๆ
      ใน Sonnet ผมไม่เห็นปรากฏการณ์แบบนั้น
      ดูเหมือนว่าปัญหาจะแทรกซึมเข้ามาได้ง่ายในระหว่างการแก้ไขแบบนี้ โดยโค้ดถูกเปลี่ยนไปใช้ไลบรารี/gem ที่ด้อยกว่า ซึ่งมีอยู่แล้วใน codebase หรือ standard library ทำให้เทสต์ผ่านและไม่ต้องเปลี่ยน Gemfile
  • SAML ไม่ปลอดภัยโดยการออกแบบ
    มีบทความเก่า ๆ ที่อธิบายเรื่องนี้ได้ดีกว่าอยู่แล้ว เช่น https://joonas.fi/2021/08/saml-is-insecure-by-design/
    ประโยคที่จำได้จากเธรดเก่านี้คือ “จงเซ็นไบต์ ไม่ใช่ความหมาย”
    ความแตกต่างระหว่าง parser เป็นสิ่งที่คาดเดาได้ และบางครั้งก็หลีกเลี่ยงไม่ได้
    สิ่งที่คุณต้องการดึงออกมาจาก response ที่ถูกเซ็นไว้มีความสำคัญมาก
    หนึ่งในปัญหากลืนไม่เข้าคายไม่ออกของ TLS สมัยใหม่คือ บางครั้งคุณอยากเชื่อถือ CA ภายในเพียงตัวเดียว ซึ่งเป็นเส้นทางที่ง่าย แต่ถ้าคุณยอมรับใบรับรอง CA ของพาร์ตเนอร์ และมีพาร์ตเนอร์หลายราย คุณจะดูแค่ใบรับรองปลายทางไม่ได้อีกต่อไป เพราะ root ของ chain ก็สำคัญต่อการตัดสินใจไม่แพ้กัน
    ดังนั้นถ้าเป็นไปได้ก็แนะนำให้หลีกเลี่ยง อัลกอริทึมการเซ็นของ AWS ด้วย
    V4 ในทางทฤษฎีปลอดภัย แต่ AWS เคยพลาดถึงสองครั้ง และ SigV1 กับ SigV3 ก็ไม่ปลอดภัยโดยการออกแบบ แต่ถึงอย่างไรก็ผ่านการทบทวนการออกแบบและถูกปล่อยออกสู่สาธารณะไปแล้ว

  • เป็นบทความที่ยอดเยี่ยม
    ตามที่ในบทความก็กล่าวถึง ต้องขอปรบมือดัง ๆ ให้ ahacker1
    เขากำลังทำงานที่ละเอียดประณีตและมีคุณค่ามากเพื่อทำให้การ implement SAML ปลอดภัย และ SSOReady ก็รู้สึกขอบคุณงานของเขาอย่างยิ่ง
    เมื่อต้นสัปดาห์นี้ WorkOS ก็โพสต์บทความดี ๆ เกี่ยวกับการร่วมงานกับ ahacker1 ด้วย: https://workos.com/blog/samlstorm

  • มีส่วนที่บอกว่า “พบกรณีที่ช่องโหว่นี้สามารถถูก exploit ได้ใน GitLab และแจ้งทีมความปลอดภัยแล้ว” สำหรับคนที่สงสัย ขอแจ้งว่า GitLab ออกแพตช์แก้ไข แล้ว
    https://about.gitlab.com/releases/2025/03/12/patch-release-g...

  • มีบทความที่เกี่ยวข้องคือบทความปี 2019 ของ Latacora ชื่อ How (not) to sign a JSON object[1]
    สรุปคือ การ เซ็นโครงสร้างแบบต้นไม้ที่ซ้อนกัน เป็นเรื่องยากและมีหลุมพรางมากมาย
    ง่ายกว่าถ้า envelope เก็บข้อความไว้เป็นสตริงดิบ แล้วเซ็นสตริงดิบเส้นนั้น
    [1]: https://www.latacora.com/blog/2019/07/24/how-not-to/

  • ข้อสรุปที่ง่ายกว่านี้คือ ควรมองหา signature ในตำแหน่งที่มันควรจะอยู่ไม่ใช่หรือ?
    อย่าใช้ XPath ที่กว้างเกินไปอย่าง “//ds:Signature” จนไปเจอ signature ใด ๆ ในตำแหน่งที่ไม่คาดคิด

    • การรับมือกับช่องโหว่มักรู้สึกว่าหละหลวมเกินไป
      ไม่ใช่แค่ผ่าตัดเอาส่วนประกอบที่อันตรายออกเท่านั้น แต่ต้องยอมทิ้งเด็กไปพร้อมกับน้ำอาบบ้าง ต้องตัดออกเป็นก้อนใหญ่และจัดการเหมือนทำเคมีบำบัด
      ผู้ดูแลระบบ IT ที่มีศักดิ์ศรีควรตัด SAML ออกจากแผนงานในอนาคต
      แนวคิด SSO ทั้งหมดก็น่าสงสัย และ XML parsing โดนเล่นงานสัปดาห์ละสองครั้งแล้ว จึงควรหลีกเลี่ยงต่อไป
      นโยบายแทนที่ XML ด้วย JSON มีอะไรผิดตรงไหน?
    • ถ้าพูดให้แรงหน่อย ข้อสรุปคือควรถือไม้กระบองใหญ่ ๆ แล้วกันไม่ให้นักพัฒนาเว็บเข้าใกล้โค้ดที่อ่อนไหวด้านความปลอดภัย
      ต้องเป็นแบบนั้นตั้งแต่การออกแบบ โปรโตคอล และรูปแบบข้อมูล
      นิสัยและข้อพิจารณาในการออกแบบของการพัฒนาเว็บทั่วไปไม่สอดคล้องกับสิ่งที่โค้ดความปลอดภัยต้องการ และบ่อยครั้งยังตรงกันข้ามกับสิ่งที่จำเป็นต่อการเขียนโค้ดที่ถูกต้องด้วย
  • น่าหงุดหงิดนิดหน่อยที่บทความบล็อกอธิบายช่องโหว่ แต่กลับละ ความแตกต่างของ parser ที่เป็นปัญหาจริงออกไป
    เหมือนเขียนบทนำของเรื่องแล้วตัดฉากไคลแมกซ์ทิ้ง

    • บทความบล็อกในคอมเมนต์ข้างเคียง <https://news.ycombinator.com/item?id=43374972> มีรายละเอียดที่เกี่ยวข้องอยู่
      มีการทำ (...//ds:DigestValue).firstChild.nodeValue โดยไม่ได้ตรวจว่า .firstChild เป็น Node หรือไม่ และในกรณีที่เป็นปัญหา มันเป็น Comment
      ดังนั้นฝั่งที่ไม่ได้ canonicalize จึงเห็น signature ที่ “ถูกบังไว้” ส่วนฝั่งที่แก้ไขแล้วซึ่งทิ้ง comment ไปกลับเห็น Node และเมื่อ implementation สองตัวตัดสินเอกสารที่เซ็นไว้ต่างกัน เรื่องไม่น่าขำก็เกิดขึ้น
    • ดูเหมือนว่าเขาไม่อยากรับผิดชอบกับการเปิดเผย zero-day ที่ทำให้สามารถ bypass สิทธิ์ในระบบจำนวนมหาศาลทั่วโลกได้โดยตรง ก่อนที่ผู้ดูแลระบบเหล่านั้นจะมีโอกาสแก้ไข
      รายละเอียดคงออกมาในไม่ช้า