F5 ตีพิมพ์ Security Advisory CVE-2021-23055 ซึ่งเป็นช่องโหว่บน NGINX Ingress Controller ผ่านการใช้งาน snippet โดย attacker ที่มีสิทธิ์ในการ deploy Ingress resource สามารถที่จะ inject configuration ใน Ingress resource ผ่านการใช้งาน snippet ให้ตัวเอง และอาจนำไปสู่การเข้าถึง secret และ resources บางอย่างได้ด้วยสิทธิ์ของ service account
Snippets คือการที่ NGINX Ingress Controller ยอมให้ผู้สร้าง Ingress สามารถแทรก NGINX Configuration ลงใน Ingress ได้ครับ ทำให้ Ingress Controller สามารถใช้ทุกๆฟังก์ชั่นที่ NGINX/NGINX Plus สามารถทำได้
จะเห็นได้ว่าช่องโหว่นี้เกิดขึ้นผ่านการใช้งาน Snippets บน Ingress resource ดังนั้นถ้าเราปิดการใช้งาน Snippets ก็จะป้องกัน CVE ตัวนี้ได้ครับ แต่ NGINX Ingress Controller โดย Default ปิดหรือเปิด Snippets มาล่ะ? มาดูกันครับ
NGINX Ingress Controller เวอร์ชั่นที่ 1 ตั้งแต่ 1.12.3 ขึ้นไป, และ NGINX Ingress Controller เวอร์ชั่นที่ 2 ตั้งแต่ 2.0.3 ขึ้นไป ได้ปิดการใช้งาน Snippets มาแล้วโดย Default
NGINX Ingress Controller เวอร์ชั่นที่ 1 ก่อนหน้า 1.12.3, และ NGINX Ingress Controller เวอร์ชั่นที่ 2 ก่อนหน้า 2.0.3 มีการเปิดใช้งาน Snippets มาโดย Default
Ref: https://support.f5.com/csp/article/K01051452?mkt_tok=NjUzLVNNQy03ODMAAAGAq7u8d08JMVjMFZs8aO5sIP39dMVJQLlnXinsl72kRey0ZHp_o5pd4i7w7dtgAPHD5IpQFb05tAcGqZYsmjGvAw8P15kJKNhdj75vC8PWwODnG3cNrA
หมายความว่า ถ้าเราใช้งาน NGINX Ingress Controller 1.12.3 หรือ 2.0.3 ซึ่งก็คือเวอร์ชั่นล่าสุดนั่นเอง และไม่ได้มีการเปิดใช้งาน Snippets เพิ่มเติม เราก็จะปลอดภัยครับ แต่คาดว่าน่าจะมีน้อยคน ที่อัพเกรดได้ไวขนาดนี้
ส่วนคนที่ใช้เวอร์ชั่นก่อนหน้านี้ ก็ค่อนข้างแน่นอนครับว่ามีความเสี่ยงกับช่องโหว่นี้ แนะนำให้รีบตรวจสอบ และแก้ไขตามวิธีการด้านล่างโดยด่วนครับ
ตัวอย่างการโจมตีที่เกิดขึ้นจริง กรณีมีการเปิดใช้งาน Snippets ทำให้ Attacker สามารถเข้าถึง Secrets ของ Cluster ได้
การตรวจสอบ ขั้นแรกเราเช็คเวอร์ชั่นของ NGINX Ingress Controller
kubectl -n nginx-ingress describe pod | grep Image:
เห็นได้ว่าเป็นเวอร์ชั่น 2.0.3 ซึ่งเป็นตัวล่าสุด มีการ Disable snippets มาโดย Default อยู่แล้ว
ตรวจสอบเพิ่มเติม ว่าไม่มีการ Enable snippets มาภายหลัง
kubectl -n nginx-ingress describe pod | grep -A5 Args:
จากรูปจะเห็นได้ว่ามี Argument -enable-snippets=true ฉะนั้น Cluster นี้จึงมีช่องโหว่ Attackers จึงสามารถโจมตีและอ่าน Secrets ได้ตามรูปที่ 1, แต่ถ้าเราตรวจเช็คแล้ว พบว่าเป็นเวอร์ชั่น 2.0.3 หรือ 1.12.3 และเช็ค Arguments แล้วไม่พบบรรทัด -enable-snippets=true ก็ถือว่า Cluster ของเราไม่เข้าข่าย CVE ตัวนี้ครับ
ตัวอย่างถัดมา กรณีเช็คแล้วพบว่าเป็นเวอร์ชั่นที่ 1 ที่ต่ำกว่า 1.12.3 หรือเป็นเวอร์ชั่นที่ 2 ที่ต่ำกว่า 2.0.3 ให้ทำการตรวจเช็ค Argument ต่อ โดยจะต้องมี "-enable-snippets=true" นี้ระบุอยู่ด้วยเท่านั้น จึงจะไม่เข่าข่าย CVE นี้ครับ
จากตัวอย่าง พบว่าไม่มีการระบุ "-enable-snippets=true" ฉะนั้น Cluster นี้เข้าข่าย CVE ตัวนี้ครับ
การแก้ไขทำได้ดังนี้ครับ
อัพเดท NGINX Ingress Controller เป็นเวอร์ชั่นล่าสุด โดยเวอร์ชั่น 2 ล่าสุดคือ 2.0.3 และเวอร์ชั่น 1 ล่าสุดคือ 1.12.3 และไม่มีการเปิดใช้งาน Snippet ก็เป็นอันเรียบร้อยครับ
ตัวอย่างการตรวจสอบเวอร์ชั่น
แต่ถ้ายังไม่สามารถอัพเดทได้ ให้เราทำการเพิ่ม Command line argument เพื่อ Disable snippet ครับ
เริ่มจาก เข้าไปแก้ไข Deployment ด้วยคำสั่ง
kubectl -n nginx-ingress edit deployment
ถ้ามีการใช้งาน NGINX Ingress แบบ Daemonsets ให้เปลี่ยนเป็น edit daemonset แทนครับ
การแก้ไข ใต้ template: spec: containers: args: เพิ่มบรรทัดนี้ครับ
จากนั้นตรวจสอบ Args พบว่ามีการเพิ่มเรื่อง enable-snippets=false แล้ว
แบบสุดท้ายครับ ถ้ามีความจำเป็นต้องใช้ Snippets เพื่อใช้งาน Advanced Features บางอย่าง จะมีหลายจุดที่เราต้องทำเพิ่มครับ เช่นจำกัดคนและสิทธิ์ในการสร้าง Ingress, การตรวจสอบ Ingress ก่อนถูกสร้าง การทำ Admission control หรืออาจจะใช้วิธีตรวจสอบ Ingress แต่ละตัวอย่างสม่ำเสมอ โดยวิธีในการตรวจสอบเบื้องต้นสามารถดูได้จาก Security Advisory แต่การใช้ Snippets ซึ่งสามารถ Configure ได้ถึงระดับ NGINX Configuration ควรต้องมีความเข้าใจใน Configuration อย่างแท้จริงจะปลอดภัยกว่าครับ
เพิ่มเติม ช่องโหว่จากการใช้งาน Snipptes กระทบทั้ง NGINX Ingress Controller, NGINX Plus Ingress Controller(by NGINX INC) และ Ingress NGINX(by CNCF) ครับ โดยฝั่ง Ingress NGINX จะได้เลข CVE-2021-25742 ตามหลัง NGINX INC อยู่ 15 วันครับ การแก้ไขทำที่ Snipptes เหมือนกัน แต่ใช้คำสั่งต่างกันครับ โดย data ใน configmap ingress-nginx-controller ครับ
data:
allow-snippet-annotations: “false”
Top comments (0)