การเปลี่ยนแปลง Nginx 1.26 ใน Apigee Edge 4.53.01

ภาพรวมการเปลี่ยนแปลงใน 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 ส่วนดังนี้

  1. ปัจจุบัน Nginx 1.26 ไม่อนุญาตให้ใช้ชื่อส่วนหัวบางชื่อที่ก่อนหน้านี้อนุญาตให้ใช้ได้ คำขอที่มีส่วนหัวเหล่านี้จะทำให้เกิดข้อผิดพลาด 400 Bad Request
  2. ปัจจุบัน Nginx 1.26 ไม่อนุญาตให้ใช้ค่าส่วนหัวบางค่าที่ก่อนหน้านี้อนุญาตให้ใช้ได้ คำขอที่มีส่วนหัวเหล่านี้จะทำให้เกิดข้อผิดพลาด 400 Bad Request ด้วย
  3. ตอนนี้ 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"}