เผยแพร่ครั้งแรกเมื่อวันที่ 5 มีนาคม 2562
หากคุณเป็นนักพัฒนาแอปพลิเคชัน ผู้ดูแลฐานข้อมูล (DBA) หรือผู้เชี่ยวชาญเทคโนโลยีประเภทใดก็ตาม การโจมตีแบบ Code Injection ควรอยู่ในเลขาระดับของคุณ
คุณมีสภาพแวดล้อมคลาวดที่ปลอดภัย การเข้าถึงฐานข้อมูลถูกล็อกไว้แล้ว แต่โค้ดแอปพลิเคชันของคุณล่ะ? แม้จะถูกมองว่าปลอดภัยกว่า ตัว No ใน NoSQLi ไม่ได้หมายความว่ามันไม่สามารถ inject ได้! NoSQL อาจเปราะบางต่อการโจมตี code injection เช่นเดียวกับโค้ดฐานข้อมูลอื่นๆ การไม่ป้องกัน code injection เหมือนกับการมีระบบรักษาความปลอดภัยสำหรับประตูแต่ปล่อยหน้าต่างหลังให้เปิดค้างไว้
Code Injection คืออะไร?
Code injection คือข้อมูลที่ไม่ได้รับการตรวจสอบความถูกต้อง ถูก inject (หรือเพิ่ม) เข้าไปในโปรแกรมที่เปราะบาง โดยที่มันจะทำงานในรูปแบบของโค้ดแอปพลิเคชัน ซึ่งมักนำไปสู่ผลลัพธ์ที่ร้ายแรง
SQLi เป็นหนึ่งในประเภทการโจมตี injection ที่พบบ่อยที่สุด และมากกว่าทศวรรษก็ยังคงแข็งแกร่ง ปัญหา injection ไม่ได้เกี่ยวข้องกับภาษาฐานข้อมูลอย่างเดียว นอกเหนือจาก SQL และ NoSQL การ inject สามารถเกิดขึ้นใน XPath®, XML Parsers, SMTP headers และบริบทอื่นๆ ได้ ในแง่ของความรุนแรง Code injection เหมือนกับการดำเนินการโค้ดระยะไกล (RCE) — จอ Game Over ของการทดสอบการเจาะระบบ
การตรวจจับและป้องกัน NoSQLi ในแอปพลิเคชันของคุณเป็นสิ่งสำคัญยิ่ง การอนุญาตให้เวกเตอร์ injection ที่ไม่ได้รับการลดทอน อาจคุกคามความปลอดภัยของฐานผู้ใช้ของคุณ แทนที่จะเป็นการสูญเสียความไว้วางใจที่อาจจบธุรกิจได้ โชคดีที่หลังจากเข้าใจกลไกแล้ว คุณสามารถ邁ก้าวสำคัญเพื่อตรวจจับและป้องกันช่องโหว่ NoSQLi ในบริการของคุณได้
ตัวอย่าง NoSQLi แบบง่าย
โดยปกติ MongoDB® รับข้อมูล Binary JSON (BSON) ที่สร้างขึ้นโดยใช้เครื่องมือสร้าง BSON query ที่ปลอดภัย แต่ในบางกรณี MongoDB ยังสามารถรับ JSON ที่ไม่ได้ถูก serialize และนิพจน์ Javascript (JS) ได้ เช่น operator $where คล้ายกับ SQL operator $where ก็มีความเสี่ยงต่อการ inject ใน NoSQL เช่นกัน อย่างไรก็ตาม ต่างจาก SQL NoSQL $where แสดงเงื่อนไขของมันใน JS หมายความว่ามันสามารถใช้พลังแสดงออกเต็มที่ของ JS เพื่อสร้างคำขอ injection ที่เป็นไปได้ แทนที่จะจำกัดเฉพาะสิ่งที่ SQL ให้มา
การผ่านรายการสตริงการ inject MongoDB ในที่เก็บสาธารณะ เช่น ตัวอย่างนี้ แสดงกลยุทธ์การ inject ทั่วไปบางส่วน ซึ่งขนานกับช่องโหว่ที่คล้ายกันใน SQL และภาษาอื่นๆ ตัวอย่างเช่น บางอย่างใช้นิพจน์คลาสสิก 1 == 1 เพื่อบังคับให้คำขอกลับค่าจริงในการพยายามอ่านทรัพยากรและสิทธิพิเศษที่ซ่อนอยู่ (หรือระดับแอดมิน):
$Where: '1 == 1'
สนิปเพ็ตอื่นๆ ทำเชียนกลยุทธ์ blind injection โดยใช้ฟังก์ชัน sleep() เพื่อทำให้ DB ช้าลงและสร้างผลข้างเคียงที่—ร่วมกับตัวกรองที่ออกแบบไว้อย่างชาญฉลาด—สามารถนับข้อมูลที่ละเอียดอ่อนได้:
';sleep(5000); ';it=new%20Date();do{pt=new%20Date();}while(pt-it<5000);
และ當然还有 老式的 数据 外泄, 其中 注入 的 查询 试图 直接 匹配 和 检索 关键 信息:
' && this.password.match(/.*/)//+%00
หลังจากตัวอย่างแรก ตัวอย่างที่เหลือสองไม่ได้ใช้ operator $where คุณไม่จำเป็นต้องมีนิพจน์ JS เป็นที่รองเท้าโจมตี NoSQL DB
การป้องกัน NoSQLi
มีกลยุทธ์ทั่วไปหลายประการที่จะปฏิบัติเมื่อพยายามสร้างสถาปัตยกรรมแอปพลิเคชันที่ทนทานต่อ NoSQLi ไม่แปลกใจที่พวกมันสอดคล้องกับคำแนะนำทั่วไป ضدการ inject
MongoDB / NoSQLi ไม่ใช่ข้อยกเว้น
บางคนมอง code injection ว่าเป็นเรื่องเฉพาะ SQL และประเมินต่ำเกินไปถึงความถูกต้องของหลักการ injection ที่นำไปประยุกต์กับบริบทอื่นๆ หวังว่าโพสต์นี้จะทำให้คุณเชื่อว่า NoSQLi เป็นจริง สิ่งนี้มีเอกสารประกอบอย่างดีในโพสต์ที่คล้ายกัน เช่น MongoDB will not prevent NoSQL injections in your Node.js app
อย่าเชื่อถือข้อมูลผู้ใช้ที่ไม่ได้รับการตรวจสอบ
จากเหตุผลด้านความปลอดภัย คุณไม่ควรเชื่อถือผู้ใช้!
สิ่งนี้อาจดูเหมือนเป็นคลิเช่ในวงการความปลอดภัย แต่ควรคาดการณ์ว่าทุก input จะถูกสำรวจด้วยเจตนาร้าย ตัวอย่าง $where ของเราก่อนหน้านี้ชี้ให้เห็นชัดเจนว่าทำไมเราจึงไม่ควรทำแบบ $where: unvalidated_input — เราอาจคิดว่าเรากำลังเปิดเผยตัวกรองให้ผู้ใช้ในจุดนี้ (ซึ่งก็แย่พอแล้ว!) ข้อเท็จจริงที่ว่าผู้ใช้นำข้อมูลที่ไม่ได้รับการตรวจสอบเข้าไปในคำขอขนาดใหญ่ ไม่ได้เป็น best practice
ระมัดระวังรายละเอียดเฉพาะภาษาหรือการบูรณาการ
แม้ NoSQLi จะไม่ได้พิเศษในเรื่องของการเป็นภูมิคุ้มกันต่อ injection (และประสบกับการโจมตีประเภทเดียวกันหลายประการ) แต่ไม่ได้หมายความว่าไม่มีกลยุทธ์ที่เฉพาะเจาะจงสำหรับ NoSQLi — หรือแม้แต่ภาษาหรือคอมโพเนนต์ที่สร้างบน NoSQL DB ตัวอย่างที่โดดเด่นคือ เนื่องจาก $where ถูกจัดรูปแบบในลักษณะที่ผ่านเป็นตัวแปร PHP ฐานข้อมูล NoSQL ที่สร้างบนแอปพลิเคชัน PHP จึงต้องคำนึงถึงเรื่องนี้และสถานการณ์ที่เป็นไปได้ของการ inject สตริงอันตรายที่เก็บอยู่ใน $where
สรุป
อีกครั้ง ตัว No ใน NoSQLi ไม่ได้หมายความว่า un-injectable! NoSQL คล้ายกับ SQL, SMTP headers, XML และบริบทอื่นๆ มีความเปราะบางต่อ code injection และหลุมโจรทั่วไปของการนำสิ่งที่ไม่ใช่โค้ดแอปพลิเคชันมาทำงานเหมือนโค้ดแอปพลิเคชัน ที่ทำให้เทคโนโลยีอื่นๆ หลายอย่างประสบปัญหา
หวังว่าโพสต์นี้ให้ความเข้าใจที่ดีขึ้นเกี่ยวกับ NoSQLi และความหมายต่อธุรกิจของคุณ ตอนนี้คุณสามารถปรับโค้ดของคุณไปสู่กระบวนการที่ทำให้มันน้อยลง ไม่แพร่หลาย และมีผลกระทบน้อยลง หากคุณต้องการคำแนะนำการจัดการ MongoDB เพื่อให้แน่ใจว่าแอปและสภาพแวดล้อมโฮสติ้งของคุณปลอดภัย Rackspace ObjectRocket มี DBA ที่มีประสบการณ์ช่วยเหลือได้
เรียนรู้เพิ่มเติมเกี่ยวกับบริการ DBA ของ Rackspace
ใช้แท็บ Feedback เพื่อแสดงความคิดเห็นหรือถามคำถาม คุณยังสามารถคลิก Sales Chat เพื่อแชททันทีและเริ่มสนทนาได้