กระบวนการที่ทำให้เกิด heap overflow ใน curl
(daniel.haxx.se)- CVE-2023-38545 ที่ถูกเปิดเผยพร้อมกับการออก curl 8.4.0 คือช่องโหว่ heap buffer overflow ที่เกิดขึ้นระหว่างการจัดการพร็อกซี SOCKS5 และเป็นช่องโหว่ระดับความรุนแรง HIGH ที่พบได้ไม่บ่อยในประเด็นความปลอดภัยของ curl
- ปัญหานี้ถูกใส่เข้ามาระหว่างการเปลี่ยนโค้ดการเชื่อมต่อ SOCKS5 ในปี 2020 จากการเรียกแบบบล็อกกิงเป็น non-blocking state machine และได้รับผลกระทบตั้งแต่ curl 7.69.0
- ตรรกะเดิมที่เปลี่ยนการแปลชื่อแบบรีโมตเป็นการแปลชื่อแบบโลคัลเมื่อพบชื่อโฮสต์ที่ยาวเกิน 255 ไบต์ ในโหมดแปลชื่อระยะไกล ได้ไปทำงานร่วมกับการเรียก state machine ซ้ำ จนทำให้สามารถคัดลอก ชื่อโฮสต์ที่ยาวเกินไป ลงในบัฟเฟอร์ขนาดเล็กได้
- เพื่อให้การโจมตีเกิดขึ้นได้ ไคลเอนต์ libcurl ต้องใช้ SOCKS5 proxy-resolver-mode และการติดตามรีไดเร็กต์อัตโนมัติ ขณะที่เซิร์ฟเวอร์ HTTPS ที่ผู้โจมตีควบคุมต้องส่ง HTTP 30x
Location:ที่มีชื่อโฮสต์ยาวเกิน 16KB แต่ไม่เกิน 64KB - ตั้งแต่ curl 8.4.0 เป็นต้นไป หากพบชื่อโฮสต์ที่ยาวเกินไปจะไม่เปลี่ยนจากการแปลชื่อแบบรีโมตเป็นแบบโลคัลอีก แต่จะคืนข้อผิดพลาดแทน และมีการเพิ่มการทดสอบเพื่อป้องกันสถานการณ์เดียวกันนี้
CVE-2023-38545 และ curl 8.4.0
- มีการเผยแพร่คำแนะนำด้านความปลอดภัยและรายละเอียดของ CVE-2023-38545 พร้อมกับการออก curl 8.4.0
- ปัญหานี้ถูกประเมินว่าเป็นปัญหาความปลอดภัยที่ร้ายแรงที่สุดของ curl ในรอบนาน และถูกจัดระดับความรุนแรงเป็น HIGH
- ข้อบกพร่องหลักคือ heap buffer overflow ที่เกิดขึ้นภายใต้เงื่อนไขเฉพาะระหว่างการจัดการการเชื่อมต่อพร็อกซี SOCKS5
SOCKS5 และวิธีการแปลชื่อ
- curl รองรับ SOCKS5 มาตั้งแต่เดือนสิงหาคม 2002
- SOCKS5 เป็นโปรโตคอลพร็อกซีที่ใช้ตั้งค่าการสื่อสารเครือข่ายผ่านเซิร์ฟเวอร์ตัวกลาง
- สามารถใช้ตั้งค่าการสื่อสารผ่าน Tor ได้
- ยังสามารถใช้เมื่อเข้าถึงอินเทอร์เน็ตจากภายในองค์กรหรือบริษัทได้ด้วย
- SOCKS5 มีวิธีแปลชื่อโฮสต์อยู่ 2 แบบ
- ไคลเอนต์ทำการ แปลชื่อในเครื่อง ก่อน แล้วส่งที่อยู่ที่แปลแล้วให้พร็อกซี
- ไคลเอนต์ส่งชื่อโฮสต์ทั้งหมดให้พร็อกซี และให้พร็อกซี แปลชื่อจากระยะไกล
การเปลี่ยนแปลงในปี 2020 ที่นำช่องโหว่เข้ามา
- ต้นปี 2020 ฟังก์ชันที่ใช้เชื่อมต่อกับพร็อกซี SOCKS5 ถูกเปลี่ยนจากการเรียกแบบบล็อกกิงเป็น non-blocking state machine
- การเปลี่ยนแปลงนี้ถูกใส่เข้า master เมื่อวันที่ 14 กุมภาพันธ์ 2020 และรวมอยู่ใน curl 7.69.0
- curl 7.69.0 จึงเป็นทั้งรุ่นแรกที่มีการปรับปรุงนี้ และกลายเป็นรุ่นแรกที่มีช่องโหว่ CVE-2023-38545 ด้วย
- เป้าหมายของการเปลี่ยนแปลงคือเพื่อให้เห็นประสิทธิภาพที่ดีขึ้นชัดเจนขึ้นเมื่อมีการส่งข้อมูลแบบขนานจำนวนมากที่ต้องผ่าน SOCKS5 ทั้งหมด
โหมดการแปลชื่อที่พังใน state machine
- ฟังก์ชัน state machine จะถูกเรียกซ้ำทุกครั้งที่มีข้อมูลเครือข่ายเข้ามาเพิ่ม จนกว่าการเชื่อมต่อจะถูกสร้างเสร็จ
- ตัวแปรภายใน
socks5_resolve_localที่ส่วนต้นของฟังก์ชันบ่งบอกว่า curl จะเป็นผู้แปลชื่อโฮสต์เอง หรือจะส่งชื่อให้พร็อกซี - ตัวแปรนี้จะถูกตั้งค่าใหม่ทุกครั้งที่ state machine ทำงาน โดยอิงจากโหมดพร็อกซีตั้งแต่ต้นการเรียกฟังก์ชัน
- เงื่อนไขในสถานะ INIT เป็นต้นตอของปัญหา
- ฟิลด์ชื่อโฮสต์ของ SOCKS5 อนุญาตได้สูงสุดเพียง 255 ไบต์
- หากชื่อโฮสต์ยาวเกิน 255 ไบต์ พร็อกซี SOCKS5 จะไม่สามารถแปลชื่อนั้นได้
- โค้ดเดิมของ curl จะเปลี่ยน
socks5_resolve_localเป็นTRUEเพื่อสลับไปใช้ โหมดแปลชื่อในเครื่อง เมื่อพบชื่อโฮสต์ที่ยาวเกินไปในโหมดแปลชื่อจากระยะไกล
- หากผู้ใช้ร้องขอการแปลชื่อจากระยะไกล curl ควรล้มเหลวแทนที่จะเปลี่ยนโหมด แต่พฤติกรรมการสลับนี้ที่ถูกเพิ่มไว้นานแล้วก็ยังคงอยู่
ลำดับที่ทำให้เกิด heap overflow
- หากเซิร์ฟเวอร์ SOCKS5 ไม่เร็วพอจน state machine ไม่ได้รับข้อมูลเครือข่ายเพิ่มเติมให้ทำงานต่อ ฟังก์ชันจะคืนค่ากลับ
- หลังจากนั้นเมื่อมีข้อมูลเข้ามาอีก ฟังก์ชัน state machine เดิมจะถูกเรียกซ้ำ
- เมื่อถูกเรียกซ้ำ
socks5_resolve_localจะถูกตั้งค่าใหม่ที่ส่วนต้นของฟังก์ชันตามโหมดพร็อกซีอีกครั้ง- ค่าที่เคยถูกเปลี่ยนเป็น
TRUEในการเรียกก่อนหน้าเพราะชื่อโฮสต์ยาวเกินไปจะไม่ถูกเก็บไว้ - ค่าจึงกลับไปเป็นสถานะที่ พร็อกซีต้องแปลชื่อจากระยะไกล อีกครั้ง
- ค่าที่เคยถูกเปลี่ยนเป็น
- curl จะสร้างเฟรมโปรโตคอลที่จะส่งให้พร็อกซีไว้ในบัฟเฟอร์หน่วยความจำ แล้วคัดลอกข้อมูลปลายทางลงไป
- เพราะค่าสถานะผิดพลาดนี้ เมื่อพยายามส่งชื่อโฮสต์ที่ยาวเกินไปตามเดิม ก็อาจเขียนทับเลยบัฟเฟอร์ปลายทางที่จัดสรรไว้ไปยัง หน่วยความจำฮีป ที่อยู่ติดกันได้
ขนาดบัฟเฟอร์และข้อจำกัดของชื่อโฮสต์
- curl นำบัฟเฟอร์ดาวน์โหลดทั่วไปกลับมาใช้ซ้ำเมื่อสร้างเฟรมโปรโตคอลที่จะส่งให้พร็อกซี
- เงื่อนไขของขนาดบัฟเฟอร์ดาวน์โหลดมีดังนี้
- ค่าเริ่มต้นคือ 16KB
- เครื่องมือ curl ตั้งขนาดบัฟเฟอร์ไว้ที่ 100KB
- แอปพลิเคชันสามารถใช้ขนาดอื่นได้ตามที่ร้องขอ
- ขนาดต่ำสุดที่อนุญาตคือ 1024 ไบต์
- หากขนาดบัฟเฟอร์ เล็กกว่า 65541 ไบต์ ก็มีโอกาสเกิด overflow นี้ได้
- ยิ่งบัฟเฟอร์เล็ก ขนาดของ overflow ที่เป็นไปได้ก็ยิ่งมาก
- แม้ฟิลด์ชื่อโฮสต์ของ URL จะไม่มีข้อจำกัดด้านขนาดในทางปฏิบัติ แต่ตัวแยกวิเคราะห์ URL ของ libcurl จะปฏิเสธชื่อที่ยาวเกิน 65535 ไบต์
- DNS อนุญาตชื่อโฮสต์ได้สูงสุดเพียง 253 ไบต์
- ชื่อที่ถูกต้องตามกฎหมายซึ่งยาวเกิน 253 ไบต์นั้นพบได้น้อย และชื่อจริงที่ยาวเกิน 1024 ไบต์แทบไม่พบเลย ดังนั้นการโจมตีจึงต้องใช้ชื่อโฮสต์ที่ยาวมากแบบจงใจ
- ในฟิลด์ชื่อโฮสต์ของ URL อนุญาตได้เพียงบาง octet เท่านั้น และค่าของไบต์ที่ไม่ถูกต้องจะถูกตัวแยกวิเคราะห์ URL ปฏิเสธ
- หาก libcurl ถูกคอมไพล์ให้ใช้ไลบรารี IDN ไลบรารีนั้นก็อาจปฏิเสธชื่อโฮสต์ที่ไม่ถูกต้องได้เช่นกัน
เงื่อนไขที่ทำให้การโจมตีเกิดขึ้นได้
- ผู้โจมตีต้องควบคุมเซิร์ฟเวอร์ HTTPS ที่ไคลเอนต์ซึ่งใช้ libcurl เข้าถึงผ่านพร็อกซี SOCKS5 ใน proxy-resolver-mode
- เซิร์ฟเวอร์ของผู้โจมตีต้องสามารถส่งรีไดเร็กต์ที่ถูกปรับแต่งในรูปแบบการตอบกลับ HTTP 30x ได้
- เฮดเดอร์
Location:ของรีไดเร็กต์สามารถมีชื่อโฮสต์ที่ยาวมากในลักษณะดังนี้Location: https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/- ความยาวของชื่อโฮสต์อยู่ในช่วง มากกว่า 16KB และไม่เกิน 64KB
- หากฝั่งไคลเอนต์ libcurl เปิดการติดตามรีไดเร็กต์อัตโนมัติไว้ และพร็อกซี SOCKS5 “ช้าพอ” ที่จะทำให้เกิดปัญหาของตัวแปรภายในนี้ ชื่อโฮสต์ที่ถูกปรับแต่งก็จะถูกคัดลอกลงในบัฟเฟอร์ที่เล็กเกินไป
- เมื่อเงื่อนไขเหล่านี้ตรงกัน ก็จะเกิดการเขียนไปยังหน่วยความจำฮีปที่อยู่ติดกัน และเกิด heap buffer overflow ขึ้น
การแก้ไขและบั๊กบาวน์ตี
- ตั้งแต่ curl 8.4.0 เป็นต้นไป หากชื่อโฮสต์ยาวเกินไป จะไม่เปลี่ยนโหมดจากการแปลชื่อจากระยะไกลเป็นการแปลชื่อในเครื่อง แต่จะคืนข้อผิดพลาดแทน
- มีการเพิ่มกรณีทดสอบเฉพาะสำหรับสถานการณ์เดียวกันนี้ด้วย
- ปัญหานี้ถูกรายงาน วิเคราะห์ และแพตช์โดย Jay Satiro
- ช่องโหว่นี้ได้รับบั๊กบาวน์ตีมูลค่าสูงที่สุดเท่าที่เคยจ่ายโดย curl จนถึงตอนนี้
- ผู้รายงานได้รับ 4,660 ดอลลาร์
- โครงการ curl ได้รับ 1,165 ดอลลาร์ ตาม นโยบาย IBB
C และภาษาแบบ memory-safe
- หาก curl ไม่ได้เขียนด้วย C แต่เขียนด้วย ภาษาแบบ memory-safe ข้อบกพร่องประเภทนี้คงไม่เกิดขึ้น
- อย่างไรก็ตาม การพอร์ต curl ไปเป็นภาษาอื่นไม่ได้อยู่ในวาระตอนนี้
- แนวทางที่เป็นจริงจึงเหลืออยู่ 2 แบบ
- ยอมรับ ใช้งาน และสนับสนุน dependency ที่เขียนด้วยภาษาแบบ memory-safe มากขึ้น
- ค่อย ๆ แทนที่บางส่วนของ curl อย่างการนำ hyper มาใช้
- การพัฒนาในลักษณะนี้ยังดำเนินไปอย่างช้ามากในปัจจุบัน และอุปสรรคที่เกี่ยวข้องก็ปรากฏชัดเจน
- ในอนาคตอันใกล้ curl จะยังคง เขียนด้วย C ต่อไป
- เมื่อนับรวม CVE ล่าสุด 2 รายการที่รายงานใน curl 8.4.0 จนถึงตอนนี้มีช่องโหว่ความปลอดภัยที่พบใน curl ราว 41% ที่อาจไม่เกิดขึ้นหากใช้ภาษาแบบ memory-safe
- อย่างไรก็ตาม ในช่วงเวลาที่ปัญหาที่เกี่ยวกับ C ราว 80% ในช่วงแรกถูกนำเข้ามา Rust ยังไม่ใช่ตัวเลือกที่ใช้งานได้จริงสำหรับจุดประสงค์นี้
ข้อบกพร่องที่ถูกค้นพบหลังผ่านไป 1315 วัน
- ข้อบกพร่องนี้ค้างอยู่ในโค้ดนาน 1315 วัน
- หากมีชุดการทดสอบที่ดีกว่านี้ก็อาจถูกค้นพบได้
- curl รัน static code analyzer หลายตัวซ้ำ ๆ แต่ไม่มีตัวใดตรวจพบปัญหาในฟังก์ชันนี้
- การปล่อยโค้ดที่มี heap overflow ออกไปยังสภาพแวดล้อมการติดตั้งมากกว่า 20,000 ล้านแห่ง ไม่ใช่ประสบการณ์ที่แนะนำให้ใครทำตาม
- สามารถดูขั้นตอนการรายงานและการจัดการก่อนเปิดเผยสู่สาธารณะได้ใน รายงานบน HackerOne
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ยังน่าทึ่งอยู่เลยที่อุปกรณ์จำนวนมากขนาดนี้พึ่งพา ไลบรารีที่แทบทั้งหมดเขียนโดยคนเพียงคนเดียว ภาระคงหนักมาก และประโยคด้านล่างก็สะท้อนเรื่องนั้นได้ดี
“พออ่านโค้ดตอนนี้แล้ว มันเป็นไปไม่ได้เลยที่จะมองไม่เห็นบั๊ก ผมรู้สึกเจ็บปวดจริง ๆ ที่ต้องยอมรับว่าผมไม่ทันสังเกตความผิดพลาดนี้ และข้อบกพร่องนั้นไม่ถูกพบในโค้ดอยู่นานถึง 1,315 วัน ขอโทษครับ ผมก็เป็นเพียงมนุษย์คนหนึ่งเท่านั้น”
ถ้า Daniel ได้เห็นสิ่งนี้ ก็อยากบอกว่าขอบคุณที่ทำงานหนัก และไม่จำเป็นต้องขอโทษเลย สุดท้ายแล้วซอร์สก็เปิดให้ทุกคนอ่านและตรวจสอบได้อยู่แล้ว
https://www.buzzfeed.com/chrisstokelwalker/the-internet-is-b...
“รายงานนี้ดูถูกต้องทุกประการ และมันเจ็บปวดลึก ๆ ในใจ”
รวมถึงประโยคในบล็อกที่ว่า “ผมไม่แนะนำประสบการณ์การปล่อย heap overflow ในโค้ดที่ถูกติดตั้งไปแล้วมากกว่า 2 พันล้านสภาพแวดล้อม” การต้องแบกรับความรับผิดชอบใหญ่ขนาดนี้โดยได้รับผลตอบแทนน้อยขนาดนั้นช่างโหดร้าย
โดยส่วนตัวแล้ว ผมมักคิดอยู่บ่อย ๆ ว่าต่อให้พยายามจดจ่อแค่ไหน เราก็พลาดสิ่งต่าง ๆ ไปมากเพียงใด กิจกรรมอย่าง code review ดูเป็นวิธีที่ดีสำหรับเรื่องนี้ คือการฝึกความใส่ใจ หรือการพัฒนาการรับรู้ภาพรวมและบริบท ตัวอย่างเช่น มีแปลงดอกไม้ที่มีคนดูแลอย่างดีอยู่ในที่ที่ผมเดินผ่านบ่อย ๆ มาหลายปี หลังจากสังเกตเห็นครั้งแรก ผมก็หยุดดูอยู่ราวหนึ่งปี แต่เมื่อไม่กี่เดือนก่อน ผมเพิ่งสังเกตเป็นครั้งแรกว่ามีแปลงดอกไม้อีกแปลงหนึ่งที่อยู่คู่กัน ห่างออกไปแค่ไม่กี่ฟุต มีความเป็นไปได้สูงว่าแปลงนั้นอยู่มาตั้งแต่แรกแล้ว แต่เพราะผมไม่รู้ด้วยซ้ำว่ามันมีอยู่ จึงไม่อาจรู้ได้แน่ชัด
ถ้าขยายความคิดนี้ไปสู่ความรู้ของมนุษยชาติทั้งหมด บางครั้งดูเหมือนว่ามีเพียงคนเดียวที่สังเกตเห็นบางอย่าง แล้วการสังเกตนั้นเปลี่ยนพฤติกรรม และเริ่มแพร่ไปถึงพวกเราทุกคน บางครั้งก็ต้องใช้ความพยายามหลายครั้งและเวลายาวนาน ผมยังสงสัยด้วยว่ายังมี ผลไม้ที่เอื้อมถึงได้ง่าย อีกมากแค่ไหนที่ยังไม่มีใครสังเกตเห็น และเชื่อว่าแค่ผนวกรวมแนวปฏิบัติที่ดีที่เรียบง่ายและเป็นพื้นฐาน ซึ่งคนที่ใส่ใจอยู่แล้วได้สร้างไว้ ก็สามารถยกระดับมาตรฐานขั้นต่ำของทุกคนได้
เรื่องของ Julia Evans ที่ https://jvns.ca/blog/2023/10/06/new-talk--making-hard-things... และของ Dan Luu ที่ https://danluu.com/p95-skill/ ก็สอดคล้องกับประเด็นนี้ สรุปแล้วรู้สึกขอบคุณ Stenberg และ curl รวมถึงผู้คนที่สร้างส่วนต่าง ๆ มากมายของโครงสร้างพื้นฐานอินเทอร์เน็ตที่เราใช้กันทุกวันราวกับเป็นเรื่องปกติ
บางครั้งหลักการ “ถ้ายังไม่พังก็อย่าไปซ่อม” ถูกตีความเป็น “อย่าสนับสนุนจนกว่ามันจะพัง” ซึ่งนำไปสู่เรื่องน่าประหลาดใจที่ไม่น่ายินดีนัก
แม้จะมีปัญหาเรื่องความยั่งยืน แต่โปรเจกต์แบบนี้คงยังมีต่อไป และขอคารวะทุกคนที่ทำงานเพื่อชุมชน ไม่ใช่แค่เพื่อตัวเอง เช่นเดียวกับ Daniel
ข้อสรุปเกี่ยวกับความปลอดภัยของหน่วยความจำและ ภาษาแบบ memory-safe สมเหตุสมผลมาก ใจความคือ
ถ้า curl เขียนด้วยภาษาแบบ memory-safe แทน C ข้อบกพร่องตระกูลนี้ก็คงเกิดขึ้นไม่ได้
แนวทางที่ดูเป็นไปได้และสมเหตุสมผลในทิศทางนั้น คือการอนุญาต ใช้งาน และสนับสนุน dependency ที่เขียนด้วยภาษาแบบ memory-safe มากขึ้น และค่อย ๆ แทนที่บางส่วนของ curl ทีละชิ้น เหมือนกับการนำ hyper มาใช้
อย่างไรก็ตาม การพัฒนาแบบนี้ตอนนี้ดำเนินไปช้าราวกับธารน้ำแข็ง และเผยให้เห็นปัญหายาก ๆ ที่เกี่ยวข้องอย่างเจ็บปวดและชัดเจน curl จะยังคงเป็น C ต่อไปในอนาคตที่คาดการณ์ได้ ใครไม่ชอบก็ลงมือพับแขนเสื้อทำเองได้
หากรวม CVE ล่าสุดสองรายการที่รายงานใน curl 8.4.0 ด้วย จนถึงตอนนี้ 41% ของยอดสะสมช่องโหว่ด้านความปลอดภัยที่พบใน curl น่าจะไม่เกิดขึ้น หากใช้ภาษาแบบ memory-safe แต่ Rust ไม่ใช่ตัวเลือกที่ใช้งานได้จริงสำหรับงานนี้ในช่วงที่ปัญหาที่เกี่ยวกับ C ราว 80% แรกถูกนำเข้ามา
มีการรัน static code analyzer หลายตัวซ้ำ ๆ แล้ว แต่ไม่พบปัญหาใด ๆ ในฟังก์ชันนี้
เป็นบทวิเคราะห์ที่ยอดเยี่ยม อย่างไรก็ตาม แม้อ่านถึง CVE แล้ว ก็ยังไม่แน่ชัดว่าได้รับผลกระทบในสถานการณ์ใดบ้าง เท่าที่เข้าใจ จะได้รับผลกระทบเมื่อเข้าเงื่อนไขด้านล่าง
ใช้พร็อกซี SOCKS5, ให้พร็อกซีนั้น resolve ชื่อโฮสต์, ขนาดบัฟเฟอร์ถูกเปลี่ยนจากค่าเริ่มต้น 100KB เป็นน้อยกว่า 65541 ไบต์ และพร็อกซี SOCKS5 ช้าเกินกว่าจะประมวลผลคำขอได้ทันที
แก้ไข: คำอธิบายเกี่ยวกับบัฟเฟอร์ไม่ถูกต้องนัก libcurl ใช้บัฟเฟอร์ดาวน์โหลดซ้ำ และค่าเริ่มต้นคือ 16KB แต่ตัว curl เองว่ากันว่าตั้งค่าเองเป็น 100KB เว้นแต่จะใช้
--limit-rateนอกจากนี้เงื่อนไขเรื่องความล่าช้าก็ผิดด้วย ตาม CVE แค่ความล่าช้าทั่วไปของเซิร์ฟเวอร์ก็มีแนวโน้ม “ช้า” พอที่จะทำให้เกิดบั๊กนี้ได้ และผู้โจมตีไม่จำเป็นต้องมีผลกระทบด้วยการทำ denial of service หรือควบคุมเซิร์ฟเวอร์ SOCKSดังนั้นเส้นทางการโจมตีดูแคบมาก เลยสงสัยว่ามีอะไรที่พลาดไปหรือเปล่า
root@1aac5e228e16:/build/curl-7.74.0# curl -vvv -x socks5h://host.docker.internal:9050 $(python3 -c "print(('A'10000), end='')")Trying 192.168.65.254:9050...* SOCKS5: server resolving disabled for hostnames of length > 255 [actual len=10000]* SOCKS5 connect to AAAAA...* Send failure: Bad file descriptor* Failed to send SOCKS5 connect request.Segmentation faulthttps://gist.github.com/xen0bit/0dccb11605abbeb6021963e2b1a8...
docker-proxyซึ่งสร้าง อุโมงค์ SOCKS5 ผ่านคอนเทนเนอร์ Docker ที่รัน openconnect VPN มีประโยชน์เมื่อต้องจัดการ VPN หลายตัวของลูกค้าหลายราย โดยแต่ละ VPN ต้องการให้ทราฟฟิกทั้งหมดของเครื่องถูกส่งไปทางตัวเองhttps://github.com/carlosonunez/docker-proxy
เนื่องจากออกแบบให้การ resolve DNS เกิดขึ้นที่ฝั่งรีโมต CVE นี้จึงใช้กับกรณีนี้โดยตรง
น่าจะเรียกได้ว่าเป็น บทวิเคราะห์ CVE ที่ดีที่สุดเท่าที่เคยอ่านมา อีกอย่าง แม้ผู้เขียนจะเป็นคนสร้างหนึ่งในซอฟต์แวร์สำคัญของยุคนี้ แต่ตลอดทั้งบทความก็ยังแสดงท่าทีถ่อมตัว น่าชื่นชมจริง ๆ นับถือมาก
if(!socks5_resolve_local && hostname_len > 255) {socks5_resolve_local = TRUE;}นี่เป็นความคิดที่แย่มาก สำหรับคนที่ใช้เครื่องมือเลี่ยงการเซ็นเซอร์เพื่อปกป้องความเป็นส่วนตัว อาจทำให้ ตัวตนรั่วไหล ผ่าน DNS ได้
ผู้เขียนก็คิดเช่นเดียวกัน
https://hackerone.com/reports/2187833
มีการบอกว่า “ถ้า curl เขียนด้วยภาษาที่ปลอดภัยด้านหน่วยความจำแทน C ข้อบกพร่องตระกูลนี้คงเป็นไปไม่ได้” แต่คงพูดได้แค่ว่าอาจเป็นไปไม่ได้ เราไม่มีทางรู้เสมอไปว่ามีวิธีหลุดออกจากกำแพงของ virtual machine ของภาษาหรือไม่ อย่างไรก็ดี ผู้เขียนเพิกเฉยต่อ ข้อจำกัดชื่อโฮสต์ DNS ที่ระบุไว้ใน RFC1123 อย่างชัดเจน และข้อจำกัดนี้ก็ถูก hardcode ไว้ในไลบรารี Java ด้วย
https://www.rfc-editor.org/rfc/rfc1123
“ชื่อโฮสต์ใน URL ไม่มีข้อจำกัดขนาดจริง ๆ แต่ตัว parser URL ของ libcurl จะปฏิเสธชื่อที่ยาวกว่า 65535 ไบต์ DNS อนุญาตชื่อโฮสต์ได้สูงสุด 253 ไบต์เท่านั้น ดังนั้นชื่อที่ถูกต้องตามกฎหมายซึ่งยาวกว่า 253 ไบต์จึงพบได้น้อย ชื่อจริงที่ยาวกว่า 1024 ไบต์แทบไม่เคยได้ยินมาก่อน”
ทุกวันนี้แม้ DNS จะถูกใช้ใน 99.9% ของกรณี แต่ก็ไม่ใช่ กลไกเดียวสำหรับ resolve ชื่อโฮสต์เป็นที่อยู่
หาไม่เจอว่า RFC กำหนดเพดานสูงสุดของขนาดชื่อโฮสต์ไว้ตรงไหน
อาจหมายถึงคอมไพเลอร์พยายามพิสูจน์ว่าหน่วยความจำจะไม่ถูกเข้าถึงนอกขอบเขต, จะไม่ถูกเข้าถึงโดยไม่มี ownership ที่ชัดเจน และจะถูกเข้าถึงเฉพาะภายในอายุของอ็อบเจ็กต์พื้นฐานเท่านั้น ตัวอย่างเช่น Rust ทำแบบนั้น
แน่นอนว่าคอมไพเลอร์อาจเพิ่มการตรวจสอบความล้มเหลวภายในและกลไกป้องกันในจุดสำคัญ ๆ ได้ Rust ไม่ได้ทำแบบนั้น แต่ในระบบที่ต้องกังวลเรื่อง bit flip ภายในรีจิสเตอร์ ก็น่าจะมีไว้จะดีกว่า เช่นสภาพแวดล้อมรังสีสูงอย่างเครื่องสแกน X-ray ซึ่ง ECC memory ตรวจจับไม่ได้
เมื่อเทียบกับเรื่องที่ต้องมีเงื่อนไขเฉพาะเจาะจงมากจึงจะใช้โจมตีได้ ก็มี การพูดเกินจริงและดราม่า ค่อนข้างมาก
อัปเดตความปลอดภัยของ Windows 10 ที่ออกมาเมื่อวานไม่ได้รวม curl เวอร์ชันใหม่มาด้วย curl ที่อยู่ใน Windows ยังเป็น 8.0.1
เป็นบทความที่ยาวและน่าสนใจ แต่สรุปได้ว่า “ดังนั้นไลบรารีระบบควรถูกเขียนด้วย ภาษาที่ปลอดภัย หรือได้รับการพิสูจน์ความถูกต้อง”
ถ้าหนึ่งในโปรแกรมเมอร์ C ที่ยอดเยี่ยมที่สุด ใจดีที่สุด และโปร่งใสที่สุดในยุคของเรา กำลังเขียนบทความแบบนี้ เราก็ควรใส่ใจ