ภาพรวมของการเปลี่ยนแปลง Nginx 1.26
การเปิดตัว Nginx 1.26 ทำให้เกิดการเปลี่ยนแปลงที่สำคัญหลายอย่างเพื่อปรับปรุงความปลอดภัยและรับประกันการปฏิบัติตามมาตรฐาน HTTP การอัปเดตที่สำคัญมีดังนี้
การจัดการช่องว่างในชื่อและค่าของส่วนหัว
เราได้เพิ่มความเข้มงวดในการปฏิบัติตาม RFC 7230 โดยเฉพาะอย่างยิ่งในส่วนของการจัดการช่องว่างในส่วนหัวเพื่อเพิ่มความปลอดภัย ดูรายละเอียดเพิ่มเติมเกี่ยวกับการเปลี่ยนแปลงเหล่านี้ได้ในภาคผนวก
การจัดการส่วนหัว Content-Length
และ Transfer-Encoding
เทคนิคที่พบบ่อยอย่างหนึ่งในการโจมตีด้วยการลักลอบส่งคำขอคือการส่งคำขอ HTTP ที่มีทั้งส่วนหัว Content-Length
และ Transfer-Encoding
แม้ว่า Apigee Edge จะได้รับการเสริมความแข็งแกร่งเพื่อป้องกันการโจมตีดังกล่าวแล้ว แต่ตอนนี้ Nginx จะบล็อกคำขอที่มีทั้ง 2 ส่วนหัวอย่างชัดเจน หากส่งคำขอดังกล่าว Nginx จะตอบกลับด้วยข้อผิดพลาด 400 Bad Request
การเข้ารหัสที่รองรับ
รายการการเข้ารหัสที่รองรับสำหรับคำขอที่อยู่ทิศเหนืออาจเปลี่ยนแปลงในรุ่นนี้ คุณสามารถตรวจสอบการเข้ารหัสที่ OpenSSL รองรับในโฮสต์เราเตอร์เพื่อดูรายการการเข้ารหัสที่ใช้ได้ซึ่งอัปเดตล่าสุด
ขนาดคีย์ที่รองรับ
ก่อนหน้านี้ ระบบยอมรับคีย์ RSA, DSA และ DH ที่น้อยกว่า 2048 บิต และคีย์ ECC ที่น้อยกว่า 224 บิตโดยค่าเริ่มต้น อย่างไรก็ตาม การอัปเดตนี้จะไม่อนุญาตให้ใช้คีย์ดังกล่าวในการเชื่อมต่อ TLS ทั้งแบบ 1 ทิศทางและ 2 ทิศทางสําหรับคําขอขาเหนืออีกต่อไป
ภาคผนวก
ช่องว่างในส่วนหัว
การเปลี่ยนแปลงหลักๆ มี 3 ประการดังนี้
- Nginx 1.26 ไม่อนุญาตให้ใช้ชื่อส่วนหัวบางชื่อที่เคยอนุญาตก่อนหน้านี้ คำขอที่มีส่วนหัวเหล่านี้จะส่งผลให้เกิดข้อผิดพลาด 400 Bad Request
- Nginx 1.26 ไม่อนุญาตให้ใช้ค่าส่วนหัวบางค่าที่เคยอนุญาตก่อนหน้านี้ คำขอที่มีส่วนหัวเหล่านี้จะส่งผลให้เกิดข้อผิดพลาด 400 Bad Request ด้วย
- ตอนนี้ 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"} |
NewLine (\n) ระหว่างชื่อส่วนหัวตามด้วย WS หรือชุด WS | {"Header\n 57Mutiline", "Value57"} {"Header\n 58Mutiline", "Value58"} |
NewLine (\n) ระหว่างชื่อส่วนหัวตามด้วย HTAB หรือชุด HTAB | {"Header\n\t73", "Value73"} {"Header\n\t\t74", "Value74"} |
ขึ้นบรรทัดใหม่ (\r) NewLine (\n) ระหว่างชื่อส่วนหัวตามด้วย HTAB หรือชุด HTAB ทันที | {"Header\r\n\t69", "Value69"} {"Header\r\n\t\t70", "Value70"} |
ขึ้นบรรทัดใหม่ (\r) NewLine (\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", "ค่า\n 61Multiline"}, {"Header62", "ค่า\n 63Multiline"}, {"Header65", "ค่า\n\t65"}, {"Header66", "ค่า\n\t\t66"}, {"Header67", "ค่า\n 67"}, {"Header68", "ค่า\n 68"} |
การเปลี่ยนแปลงการตอบกลับ HTTP ที่ไม่สําเร็จ
ส่วนนี้จะกล่าวถึงส่วนหัวที่ Nginx เวอร์ชันเก่าอนุญาต แต่โปรแกรมประมวลผลข้อความต้นทางปฏิเสธ ซึ่งส่งผลให้เกิดรหัสสถานะ 400 อย่างไรก็ตาม ใน Nginx 1.26 ส่วนหัวดังกล่าวทําให้ Nginx ทำงานไม่สําเร็จโดยตรง ซึ่งทําให้ส่งต่อคําขอไปยังโปรแกรมประมวลผลข้อความไม่ได้
สำหรับไคลเอ็นต์ที่ส่งส่วนหัวดังกล่าว รหัสสถานะ HTTP จะยังคงเป็น 400 อย่างไรก็ตาม เนื้อหาการตอบกลับ HTTP อาจเปลี่ยนแปลงเนื่องจากตอนนี้ Nginx จะสร้างข้อผิดพลาดแทนที่จะเป็นโปรแกรมประมวลผลข้อความ
สถานการณ์ | ตัวอย่าง |
---|---|
HTAB หรือ WS ระหว่าง HEADERNAME
ผู้ประมวลผลข้อความจะปฏิเสธคำขอดังกล่าว เมื่อใช้ 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"} |