HTTP request smuggling คืออะไร?

Kaori Takase
4 min readJun 12, 2021
https://i1.wp.com/lab.wallarm.com/wp-content/uploads/2020/10/HTTP2-post.png?fit=6144%2C3456&ssl=1

Web Application ในปัจจุบันมักใช้ Server HTTP แบบลูกโซ่ ระหว่างผู้ใช้กับ ultimate application logic โดยผู้ใช้ส่ง request ไปยัง front-end server (บางครั้งเรียกว่า load balancer หรือ reverse proxy) และ server นี้จะส่งต่อ request ไปยัง back-end servers อย่างน้อยหนึ่ง Server

ประเภทนี้มีมากขึ้นเรื่อยๆ และในบางกรณีก็หลีกเลี่ยงไม่ได้ใน Application บน Cloud ที่ทันสมัย

มาดูขั้นตอนการทำงานกันนะคะ

  1. เมื่อ front-end server ส่งต่อ request HTTP ไปยัง back-end server โดยปกติแล้วจะส่ง request หลายรายการผ่านการเชื่อมต่อ back-end network เดียวกัน เพราะวิธีนี้มีประสิทธิภาพและประสิทธิผลมากกว่า
  2. request HTTP จะถูกส่งทีละรายการ และ Server ที่รับparses HTTP request headers เพื่อกำหนดว่า request แรกสิ้นสุดที่ใด และเตรียม request ถัดไปแล้วเริ่มต้นใหม่

3. ในเหตุการณ์นี้ front-end และ back-end systems ทำการตกลง เกี่ยวกับขอบเขตระหว่าง request เป็นสิ่งที่สำคัญ ไม่เช่นนั้น Hacker อาจสามารถส่ง request ไปยัง front-end ซึ่งถ้าเป็น request ที่ไม่ชัดเจน back-end systems ตีความต่างกัน

4. ในที่นี้ Hacker เป็นส่วนหนึ่งของ request front-end หลังจากนั้น back-end server ตีความเข้าร่วมกันซึ่งเป็นจุดเริ่มต้นของ request ถัดไป แล้วจุดนี้แหละที่ Hacker สามารถรบกวน application ของการประมวลผล request นั้น จึงเรียกว่า HTTP request smuggling attack และจะส่งผลร้ายแรงต่อ application เรา

ช่องโหว่ HTTP request smuggling เกิดขึ้นได้อย่างไร?

จากที่เราไปค้นคว้ามา เรากำหนดว่าเกิดขึ้นได้2วิธี

วิธี1.Content-Length header เป็นแบบตรงไปตรงมา แล้วมีการระบุเนื้อความเป็น byte

ตัวอย่างเช่น

2.Transfer-Encoding header

สามารถใช้เพื่อระบุว่า message body ใช้การ encoding แบบเป็นกลุ่ม ซึ่งหมายความว่าเนื้อหาของข้อความมีข้อมูลอย่างน้อยหนึ่งส่วน แต่ละส่วน ประกอบด้วย size เป็น bytes (แสดงเป็นเลข hexadecimal) ตามด้วยขึ้นบรรทัดใหม่ ตามด้วย chunk content ข้อความจะสิ้นสุดลงด้วยchunk ของ size zero

ตัวอย่างเช่น:

เนื่องจากข้อกำหนด HTTP มีวิธีการที่แตกต่างกันสองวิธีในการระบุความยาวของ HTTP message จึงเป็นไปได้ที่ข้อความเดียวจะใช้ทั้งสองวิธีพร้อมกัน ในลักษณะที่ขัดแย้งกันเอง ข้อมูลจำเพาะ HTTP พยายามป้องกันปัญหานี้โดยระบุว่า ถ้ามีทั้งContent-Length และ Transfer-Encoding ควรละเว้นส่วน Content-Length header นี่ เพราะอาจเพียงพอแล้วที่จะหลีกเลี่ยงความกำกวมเมื่อมี Server เดียวที่เล่นอยู่ แต่ไม่ใช่เมื่อ Server สองตัวหรือมากกว่า ถูกเชื่อมโยงเข้าด้วยกัน ในสถานการณ์เช่นนี้ ปัญหาอาจเกิดขึ้นได้จากสองสาเหตุคือ :

1. Serverบางเครื่องไม่รองรับ Transfer-Encoding header ใน request

2. Serverบางเครื่องที่สนับสนุน Transfer-Encoding header ข้อมูลอาจถูกชักจูงให้ไม่ประมวลผลหาก header ถูกทำให้สับสนในทางใดทางหนึ่ง

หาก Server front-end และ back-end ทำงานแตกต่างกันโดยสัมพันธ์กับ Transfer-Encoding header Server อาจไม่เห็นด้วยกับขอบเขตระหว่าง request ที่ต่อเนื่องกัน ซึ่งนำไปสู่ช่องโหว่ของ request smuggling

วิธีการโจมตี HTTP request smuggling

การโจมตี request smuggling เกี่ยวข้องกับการวางทั้งส่วน Content-Length header และ Transfer-Encoding header ลงใน request HTTP เดียวกันและจัดการสิ่งนี้เพื่อให้ front-end และ back-end server ประมวลผล request ต่างกัน วิธีที่แน่นอนในการดำเนินการนี้ขึ้นอยู่กับลักษณะการทำงานของ 2 header ดังนี้

  • CL.TE: front-end serverใช้ Content-Length header และ back-end server ใช้ Transfer-Encoding header
  • TE.CL: front-end server ใช้ Transfer-Encoding header และ back-end serverใช้ Content-Length header
  • TE.TE:front-end และ back-end servers รองรับ Transfer-Encoding header แต่ Server ตัวใดตัวหนึ่งสามารถถูกชักจูงให้ไม่ประมวลผลโดยทำให้header สับสนในทางใดทางหนึ่ง

ช่องโหว่ของแต่ละserver

1.CL.TE vulnerabilities

front-end server ใช้ Content-Length header และ back-end server ใช้ Transfer-Encoding header เราสามารถทำการโจมตี HTTP request smuggling ได้ดังนี้:

front-end server ประมวลผล Content-Length header และกำหนด request ของ body เท่ากับ13 bytes ยาวไปจนถึงจุดสิ้นสุดของ SMUGGLED request นี้จะถูกส่งต่อไปยัง back-end server

back-end server ประมวลผล Transfer-Encoding header ดังนั้นจะถือว่า message body เหมือนกับการใช้การเข้ารหัสแบบกลุ่ม โดยจะประมวลผลส่วนแรกซึ่งระบุว่ามีความยาวเป็น 0 และจะถือว่าเป็นการยกเลิก request byte ต่อไปนี้คือ SMUGGLED ไม่ถูกประมวลผล และback-end server นี้เป็นจุดเริ่มต้นของ request ถัดไปตามลำดับ

2.TE.CL vulnerabilities

front-end server ใช้ Transfer-Encoding header และ back-end server ใช้ Content-Length header เราสามารถทำการโจมตี HTTP request smuggling ได้ดังนี้:

front-end server จะประมวลผล Transfer-Encoding header ดังนั้นจะถือว่า message body เหมือนกับการใช้การเข้ารหัสแบบกลุ่ม

  • ประมวลผลกลุ่มแรก ซึ่งระบุว่ามีความยาว 8 byte จนถึงจุดเริ่มต้นของบรรทัดที่ตามหลัง SMUGGLED
  • ประมวลผลส่วนที่สองซึ่งระบุว่ามีความยาวเป็น 0 และเป็นการยกเลิก request request นี้จะถูกส่งต่อไปยัง back-end server

back-end serverประมวลผล Content-Length header และกำหนดว่าเนื้อหา request มีความยาว 3 byte จนถึงจุดเริ่มต้นของบรรทัดที่ตามมา 8 byte ต่อไปนี้ ซึ่งเริ่มต้นด้วย SMUGGLED จะไม่ประมวลผล และback-end server จะเป็นจุดเริ่มต้นของ request ต่อไปตามลำดับ

3. พฤติกรรมของ TE.TE: ทำให้ TE header สับสน

ทั้ง front-end และ back-end servers รองรับ Transfer-Encoding header แต่ Server ตัวใดตัวหนึ่งสามารถถูกชักจูงให้ไม่ประมวลผลโดยทำให้ header สับสนในทางใดทางหนึ่ง

มีวิธีที่อาจไม่มีที่สิ้นสุดในการทำให้ Transfer-Encoding header ให้เกิดความสับสน

ตัวอย่างเช่น:

ในการเปิดเผยช่องโหว่ของ TE.TE จำเป็นต้องค้นหารูปแบบต่างๆ ของ Transfer-Encoding header เพื่อให้มี front-end server หรือ back-end server เพียงเครื่องเดียวที่ประมวลผล ในขณะที่ Server อื่นละเว้น

การโจมตีที่เหลือจะมีรูปแบบเดียวกับช่องโหว่ CL.TE หรือ TE.CL ทั้งนี้ขึ้นอยู่กับว่าเป็นfront-end server หรือ back-end server ที่สามารถกระตุ้นให้ไม่ประมวลผล Transfer-Encoding header ให้เกิดความสับสนได้

ต่อไปนี้เป็นภาพที่สรุปช่องโหว่ของแต่ละ server นะคะ

https://pbs.twimg.com/media/EKi5edAUUAAIPIK?format=jpg&name=large

วิธีป้องกันช่องโหว่HTTP request smuggling

ช่องโหว่HTTP request smuggling เกิดขึ้นในสถานการณ์ที่ front-end server ส่งต่อ request หลายรายการไปยัง back-end server ผ่านการเชื่อมต่อเครือข่ายเดียวกัน และ protocol ที่ใช้สำหรับการเชื่อมต่อ back-end มีความเสี่ยงที่ server ทั้งสองไม่เห็นด้วยกับขอบเขตระหว่าง request วิธีทั่วไปบางประการในการป้องกันช่องโหว่HTTP request smuggling ที่เกิดขึ้นมีดังนี้:

  • ปิดการใช้งานการเชื่อมต่อ back-end connection ซ้ำเพื่อส่ง request back-end แต่ละรายการผ่านการเชื่อมต่อเครือข่ายที่แยกจากกัน
  • ใช้ HTTP/2 สำหรับการเชื่อมต่อ back-end เนื่องจาก protocol นี้ป้องกันความกำกวมเกี่ยวกับขอบเขตระหว่าง request
  • ใช้ Web server เดียวกันสำหรับ front-end server และ back-end server เพื่อให้สอดคล้องกันเกี่ยวกับขอบเขตระหว่าง request

ในบางเคส สามารถหลีกเลี่ยงช่องโหว่ได้โดยการทำให้ front-end server ปรับ request ที่คลุมเครือให้เป็นปกติ หรือทำให้ back-end server ปฏิเสธ request ที่คลุมเครือและปิดการเชื่อมต่อเครือข่าย อย่างไรก็ตาม วิธีการเหล่านี้มีแนวโน้มที่จะเกิดข้อผิดพลาดมากกว่าวิธีการป้องกันช่องโหว่ HTTP request smuggling ที่ระบุไว้ข้างต้น

reference:

--

--