ภาพรวมการเปลี่ยนแปลงใน Nginx 1.26
การเปิดตัว Nginx 1.26 ได้นำมาซึ่งการเปลี่ยนแปลงที่สำคัญหลายอย่างเพื่อเพิ่มความปลอดภัยและรับรองการปฏิบัติตามมาตรฐาน HTTP การอัปเดตที่สำคัญมีดังนี้
การจัดการการเว้นวรรคในชื่อและค่าของส่วนหัว
เพื่อปรับปรุงความปลอดภัย เราได้เพิ่มความเข้มงวดในการปฏิบัติตาม RFC 7230 โดยเฉพาะอย่างยิ่งในเรื่องการจัดการช่องว่างในส่วนหัว ดูรายละเอียดเพิ่มเติมเกี่ยวกับการเปลี่ยนแปลงเหล่านี้ได้ในภาคผนวก
การจัดการส่วนหัว Content-Length
และ Transfer-Encoding
เทคนิคที่ใช้กันโดยทั่วไปในการโจมตีแบบ Request Smuggling อย่างหนึ่งคือการส่งคำขอ HTTP ที่มีทั้งส่วนหัว Content-Length
และ Transfer-Encoding
แม้ว่า Apigee Edge จะได้รับการเสริมความแข็งแกร่งเพื่อป้องกันการโจมตีดังกล่าวอยู่แล้ว แต่ตอนนี้ Nginx จะบล็อกคำขอที่มีทั้ง 2 ส่วนหัวอย่างชัดเจน หากมีการส่งคำขอดังกล่าว Nginx จะตอบกลับด้วยข้อผิดพลาด 400 Bad Request
การเข้ารหัสที่รองรับ
รายการการเข้ารหัสที่รองรับสำหรับคำขอขาขึ้นอาจมีการเปลี่ยนแปลงในการเปิดตัวนี้ คุณสามารถตรวจสอบการเข้ารหัสที่ OpenSSL รองรับในโฮสต์เราเตอร์เพื่อดูรายการการเข้ารหัสที่พร้อมใช้งานที่อัปเดตแล้ว
ขนาดคีย์ที่รองรับ
ก่อนหน้านี้ระบบจะยอมรับคีย์ RSA, DSA และ DH ที่มีขนาดเล็กกว่า 2048 บิต และคีย์ ECC ที่มีขนาดเล็กกว่า 224 บิตโดยค่าเริ่มต้น อย่างไรก็ตาม การอัปเดตนี้จะไม่อนุญาตให้ใช้คีย์ดังกล่าวสำหรับการเชื่อมต่อ TLS แบบทางเดียวและแบบ 2 ทางสำหรับคำขอขาขึ้นอีกต่อไป
ภาคผนวก
ช่องว่างในส่วนหัว
การเปลี่ยนแปลงหลักๆ มี 3 ส่วนดังนี้
- ปัจจุบัน Nginx 1.26 ไม่อนุญาตให้ใช้ชื่อส่วนหัวบางชื่อที่ก่อนหน้านี้อนุญาตให้ใช้ได้ คำขอที่มีส่วนหัวเหล่านี้จะทำให้เกิดข้อผิดพลาด 400 Bad Request
- ปัจจุบัน Nginx 1.26 ไม่อนุญาตให้ใช้ค่าส่วนหัวบางค่าที่ก่อนหน้านี้อนุญาตให้ใช้ได้ คำขอที่มีส่วนหัวเหล่านี้จะทำให้เกิดข้อผิดพลาด 400 Bad Request ด้วย
- ตอนนี้ Nginx จะปฏิเสธส่วนหัวบางรายการที่ก่อนหน้านี้ Nginx ยอมรับ แต่ทำให้เกิดข้อผิดพลาดในสตรีมดาวน์ในตัวประมวลผลข้อความโดยตรง แม้ว่าส่วนหัวเหล่านี้จะยังคงทำให้ API ทำงานล้มเหลว แต่ข้อความแสดงข้อผิดพลาดของ HTTP จะมีการเปลี่ยนแปลง
ส่วนด้านล่างนี้มีตัวอย่างชื่อส่วนหัวและค่าส่วนหัวต่างๆ ที่ไม่อนุญาต นี่เป็นเพียงตัวอย่างเท่านั้น และอาจไม่ใช่รายการโดยสมบูรณ์ เราขอแนะนำให้ปฏิบัติตามหลักเกณฑ์ของ RFC 7230 สำหรับส่วนหัว
การเปลี่ยนแปลงชื่อส่วนหัว
ส่วนนี้แสดงชื่อส่วนหัวต่างๆ ที่อนุญาตใน Nginx 1.20.1 แต่ไม่อนุญาตใน Nginx 1.26
สถานการณ์ | ตัวอย่างชื่อส่วนหัว |
---|---|
อักขระควบคุมที่จุดเริ่มต้น จุดสิ้นสุด หรือระหว่างชื่อส่วนหัว | { '\u0001'Header0, Value0 } { Header6'\u0002', Value6 } { Header'\u0005'4, Value4 } |
ช่องว่างขึ้นต้นและต่อท้ายในชื่อส่วนหัว | {"Header2 ", "Value2"} {" Header3", "Value3"} {" Header4 ", "Value4"} |
HTAB ที่นำหน้าและต่อท้ายในชื่อส่วนหัว | {"\tHeader11", "Value11"} {"Header12\t", "Value12"} {"\tHeader13\t", "Value13"} |
การรวม HTAB, WS ที่นำหน้าและต่อท้ายในชื่อส่วนหัว | {"\t Header24", "Value24"} {" \tHeader25", "Value25"} {"Header26 \t", "Value26"} {"Header27\t ", "Value27"} |
บรรทัดใหม่ (\n) ระหว่างชื่อส่วนหัวตามด้วย WS หรือชุด WS โดยไม่เว้นวรรค | {"Header\n 57Mutiline", "Value57"} {"Header\n 58Mutiline", "Value58"} |
บรรทัดใหม่ (\n) ระหว่างชื่อส่วนหัวตามด้วย HTAB หรือชุด HTAB โดยไม่เว้นวรรค | {"Header\n\t73", "Value73"} {"Header\n\t\t74", "Value74"} |
การขึ้นบรรทัดใหม่ (\r) การขึ้นบรรทัดใหม่ (\n) ระหว่างชื่อส่วนหัวตามด้วย HTAB หรือชุด HTAB โดยไม่เว้นวรรค | {"Header\r\n\t69", "Value69"} {"Header\r\n\t\t70", "Value70"} |
การขึ้นบรรทัดใหม่ (\r) การขึ้นบรรทัดใหม่ (\n) ระหว่างชื่อส่วนหัวตามด้วย WS หรือชุด WS ทันที | {"Header\r\n 71", "Value71"} {"Header\r\n 72", "Value72"} |
การเปลี่ยนแปลงค่าส่วนหัว
ส่วนนี้แสดงค่าส่วนหัวต่างๆ ที่อนุญาตใน Nginx 1.20.1 แต่ไม่อนุญาตใน Nginx 1.26
สถานการณ์ | ตัวอย่าง |
---|---|
\r\n หรือการรวมกันของ \r\n กับ WS หรือ HTAB ที่อนุญาตในระหว่าง HEADERVALUE |
{"Header47", "Value47\r\n MultiLine"}, {"Header48", "Value48\r\n MultiLine"}, {"Header49b", "Value49b\r\n \r\nMultiLine"}, {"Header50", "Value50 \r\n MultiLine"}, {"Header51", "Value51\r\n\tMultiLine"}, {"Header52", "Value52\r\n\t\tMultiLine"}, {"Header53", "Value53\t\r\n\tMultiLine"} |
\n หรือการรวม \n กับ WS หรือ HTAB ที่อนุญาตระหว่าง HEADERVALUE |
{"Header61", "Value\n 61Multiline"}, {"Header62", "Value\n 63Multiline"}, {"Header65", "Value\n\t65"}, {"Header66", "Value\n\t\t66"}, {"Header67", "Value\n 67"}, {"Header68", "Value\n 68"} |
การเปลี่ยนแปลงในการตอบกลับเมื่อ HTTP ล้มเหลว
ส่วนนี้ครอบคลุมส่วนหัวที่ Nginx เวอร์ชันเก่าอนุญาต แต่โปรแกรมประมวลผลข้อความต้นทางปฏิเสธ ซึ่งส่งผลให้เกิดรหัสสถานะ 400 อย่างไรก็ตาม ใน Nginx 1.26 ส่วนหัวดังกล่าวจะทำให้เกิดข้อผิดพลาดใน Nginx โดยตรง ซึ่งจะป้องกันไม่ให้ส่งต่อคำขอไปยังตัวประมวลผลข้อความ
สำหรับไคลเอ็นต์ที่ส่งส่วนหัวดังกล่าว รหัสสถานะ HTTP จะยังคงเป็น 400 อย่างไรก็ตาม เนื้อหาการตอบกลับ HTTP อาจเปลี่ยนแปลงเนื่องจากตอนนี้ Nginx จะสร้างข้อผิดพลาดแทนโปรแกรมประมวลผลข้อความ
สถานการณ์ | ตัวอย่าง |
---|---|
HTAB หรือ WS ระหว่าง HEADERNAME
โดย Message Processor จะปฏิเสธคำขอดังกล่าว เมื่อใช้ Nginx 1.26 คำขอเหล่านี้จะถูกปฏิเสธโดย Nginx เอง ผู้ใช้ API จะได้รับการตอบกลับเป็นข้อผิดพลาด 400 พร้อมข้อความแสดงข้อผิดพลาดของ Nginx ในเนื้อหา |
{"Header 5", "Value5"}, {"Header\t14", "Value14"}, {"Header\t 32", "Value32"}, {"Header \t33", "Value33"}, {"Header- 36", "Value36"}, {"Header-\t40", "Value40"}, {"Header 4a", "Value4a"}, {"Header\t 59", "Value59"}, {"Header\t 60", "Value60"} |