ภาพรวมของการเปลี่ยนแปลงใน 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"} |
บรรทัดใหม่ (\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
ผู้ประมวลผลข้อความจะปฏิเสธคำขอดังกล่าว เมื่อใช้ 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"} |