สวัสดีคุณผู้อ่านทุกท่าน วันนี้ผมมีบทความสำหรับความรู้เบื้องต้นเกี่ยว NoSQL Injection ซึ่งอยู่ใน OWASP Top 10 Web Application Security Risks ข้อ 3 หรือ A03:2021-Injection โดยหัวข้อหลัก ๆ ในวันนี้จะเกี่ยวกับ NoSQL injection คืออะไร ต่างจาก SQL injection อย่างไร สาเหตุที่เกิดและวิธีป้องกันครับ
แต่! ก่อนที่เราจะไปศึกษาว่า NoSQL injection คืออะไร เราต้องรู้ก่อนใช่ไหมครับว่า NoSQL คืออะไร เราไปที่หัวข้อแรกกันเลยครับ ผมจะพยายามอธิบายคร่าว ๆ และกระชับเพื่อให้ผู้ที่พึ่งศึกษาเบื้องต้นเข้าใจนะครับ
NoSQL คืออะไร
NoSQL นั้นย่อมากจาก non-SQL หรือบางคนเรียก Not only SQL หมายถึง ระบบฐานข้อมูลชนิดหนึ่งซึ่งค่อนข้างมีความยืดหยุ่นสูงในการเก็บข้อมูลไว้ในรูปแบบต่าง ๆ ส่วนมากจะเก็บข้อมูลข้อมูลไว้ในรูปแบบ key-value pairs, documents, column-family หรือ data graphs เป็นส่วนใหญ่ และตามชื่อเลยครับ Non-SQL คือไม่ซัพพอร์ตตัว Structured Query Language (SQL) หรือ ภาษา SQL นั่นเอง ซึ่งหลายปีมานี้ มีฐานข้อมูล NoSQL ที่มีชื่อหลายตัวมากที่คุณผู้อ่านอาจจะเคยได้ยินผ่าน ๆ เช่น MongoDB, Apache Cassandra, Apache HBase, Apache CouchDB, Neo4j, RavenDB, Redis, OrientDB, DynamoDB, HyperTable, Google Cloud Datastore, and many more.
NoSQL Injection คืออะไร
NoSQL injection นั้นเกิดจากข้อบกพร่องของ Security ที่เกิดจากตัว Web application ที่ใช้ฐานข้อมูลเป็น NoSQL ซึ่งจะมีการลงรายละเอียดในหัวข้อต่อ ๆ ไปนะครับ โดยส่วนมาก ช่องโหว่ NoSQL injection นั้นเกิดเมื่อ Web Application รับ Input ของ ผู้ใช้งานโดยตรงมา process โดยที่ไม่มีการตรวจสอบหรือกรอง input ต่าง ๆ นั่นเองซึ่งจริง ๆ แล้วตัวของ NoSQL injection นั้น มีการโจมตีที่คลายคลึงกับตัว SQL injection เลย เช่น สามารถ Bypass Authentication, สามารถดึงหรือกรองข้อมูลที่ละเอียดอ่อนในฐานข้อมูลได้ หรือแม้กระทั่งยึดฐานข้อมูลเลยก็ได้
ความแตกต่างระหว่าง NoSQL และ SQL Injection
ข้อแตกต่างหลัก ๆ เลยที่เห็นได้ชัดระหว่าง NoSQL และ SQL นั้น คือ Syntax (วากยสัมพันธ์) และ grammar (ไวยกรณ์) ของการ Query. ซึ่ง NoSQL ไม่มี Syntax (วากยสัมพันธ์) และ grammar (ไวยกรณ์) ที่เป็นกลางหรือแบบสำเร็จ ซึ่งรูปแบบของการ Query นั้นขึ้นอยู่กับชนิดของฐานข้อมูลที่ใช้และภาษาที่ใช้เขียนของตัวเว็บหรือ API นั้น ๆ ซึ่งหมายความว่า Query จะมีความหลากหลายไม่ได้ขึ้นอยู่ที่ฐานข้อมูลอย่างเดียว แต่ขึ้นอยู่กับภาษาที่ใช้เขียนด้วย เช่น (e.g. Python, PHP, Node.js, etc.) หรือตัวของ framework เองก็ตาม เช่น Spring Framework
ซึ่ง NoSQL injection นั้น สามารถโจมตีได้ทั้ง Application layer และ Database Engine ในขณะที่ตัว SQL Injection สามารถ execute ได้แค่ที่ตัว Database Engine
NoSQL นั้นสามารถ execute payload ได้ทั้งที่ฐานข้อมูลและตัว Application ขึ้นอยู่กับ Data model และ NoSQL API มีการออกแบบโครงสร้างมาแบบไหน แต่โดยทั่วไปมักจะเกิดที่ application layer.
สามารถใช้ Payload SQL injection กับฐานข้อมูล NoSQL ได้ไหม
การใช้ Payload SQL Injection นั้น ไม่สามารถใช้กับฐานข้อมูล NoSQL ตรง ๆ ได้เนื่องจาก NoSQL ใช้ภาษา Query ที่เป็นรูปแบบเฉพาะและไม่ซัพพอร์ตตัว Structured Query Language (SQL) หรือภาษา SQL ถ้าต้องการที่จะโจมตีฐานข้อมูล NoSQL ผู้โจมตีจะต้องปรับแต่งตัว SQL injection เทคนิคเพื่อให้เข้ากับรูปแบบเฉพาะของภาษา NoSQL นั้น ๆ ซึ่งมักจะใช้ภาษาเดียวกับ Database Engine
NoSQL injection เกิดขึ้นได้อย่างไร
NoSQL Injection เกิดขึ้นเมื่อมีการแทรก Query มากับ input ที่ผู้ใช้งานเป็นผู้ส่ง โดยที่ไม่มีการกรองหรือตรวจสอบ ทำให้ ผู้โจมตีสามารถแทรกชุดคำสั่งอันตราย ทำให้ฐานข้อมูล Execute ชุดคำสั่งที่ถูกแทรกเข้ามา และทำงานนอกเหนือจากการใช้งาน
ในบางฐานข้อมูล NoSQL นั้นใช้ Application code ในการ Query ผู้โจมตี ไม่ได้แค่สามารถ แทรก Input อันตราย มาให้ฐานข้อมูล Execute คำสั่งที่นอกเหนือจากการใช้งานได้ แต่สามารถ แทรก input อันตราย มาให้ตัว Application ทำการ Execute คำสั่งที่นอกเหนือจากการใช้งานได้ ซึ่งสามารถยึด server หรือ exploit ช่องโหว่ที่นอกเหนือจากขอบเขตของตัวฐานข้อมูลได้ ทำให้ในบางกรณี NoSQL Injection นั้นมีความรุนแรงกว่า SQL Injection
วิธีหลีกเลี่ยงหรือวิธีป้องกัน SQL Injection
NoSQL Attack สามารถป้องกันหรือหลีกเลี่ยงได้ค่อนข้างยากกกว่าตัว SQL Injection เพราะหลาย ๆ ฐานข้อมูล NoSQL นั้น ไม่ได้มีฟังก์ชันหรือ Standard Code เพื่อความปลอดภัยไว้ให้ ซึ่งต้องสร้างขึ้นเองไว้เพื่อใช้งาน แต่จะมี Document และ Security Guideline สำหรับ NoSQL นั้น ๆ เพื่อแนะแนวทางความปลอดภัย
โดยหลัก ๆ แล้วจะมีอยู่ 3 ทางที่สามารถป้องกัน NoSQL Injection ได้ คือ
- ใช้เวอร์ชันล่าสุด กล่าวคือ NoSQL หลาย ๆ ตัวนั้นมีการมีอัปเดตและแก้ไขช่องโหว่ อยู่ตลอด ซึ่งสำคัญมากที่เราจะต้องอัปเดตเวอร์ชันใหม่เรื่อย ๆ เพื่อป้องกันช่องโหว่ที่มีการคนพบใน NoSQL ทุก ๆ วัน เช่น MongoDB เวอร์ชันเก่าจะมีความปลอดภัยน้อยกว่า และเสี่ยงต่อการโดนโจมตี แต่เวอร์ชันใหม่มีความปลอดภัยมากกว่าเสี่ยงน้อยกว่า
- การตรวจสอบ, กรอง Input หรือ Encode ที่มาจาก ผู้ใช้งานใน Application Code ซึ่งถือว่าเป็นวิธีที่ดีที่สุดเลยก็ว่าได้ เนื่องจากเป็นการหลบเลี่ยงคำสั่งที่แทรกเข้ามาเพื่อการทำงานที่เกินความจำเป็น (Malicious Code) คือการตรวจสอบ และ Encode Input ทั้งหมดของผู้ใช้งาน เพื่อไม่ให้เกิด Injection ต่าง ๆ นั่นเอง
- การใช้ Firewall ต่าง ๆ ในการดัก Input ที่ไม่ประสงค์ดี
แนะนำ LAB
มี LAB มาแนะนำส่งท้ายกันสักหน่อยครับ ซึ่ง LAB นี้เป็น LAB NoSQL Injection ชื่อ LAB : NoSQL Basics ของ TryHackMe ไปลองเล่นกันได้นะครับ ตามลิงก์ด้านล่างเลยครับผม
https://tryhackme.com/room/nosqlinjectiontutorial#
LAB ข้างต้นนี้เหมาะสำหรับผู้เริ่มต้นศึกษา ซึ่งจะเข้าใจได้ง่าย โดยภายใน LAB จะมีการสอน NoSQL เบื้องต้นจะเน้นไปที่ MongoDB ว่ามันคืออะไร ทำงานยังไง วิธี Query Document เบื้องต้น เช่น
ตัวอย่างการ Query เบื้องต้น
สมมุติว่าเรามี 3 Document ดังภาพ
ถ้าเราต้องการ Query Document ที่มี last_name เป็น Sandler Query หน้าตาจะเป็นดังนี้
[‘last_name’ => ‘Sandler’]
ถ้าเราต้องการ Query Document ที่มี gender เป็น Male และมี last_name เป็น Philips หน้าตาจะเป็นดังนี้
[‘gender’ => ‘male’, ‘last_name’ => ‘Phillips’]
แต่ถ้าหากต้องการ Query Document ที่ age น้อยกว่า 50 จะมีการใช้ MongoDB Operator เข้ามาช่วยด้วย หน้าตาจะเป็นดังนี้
[‘age’ => [‘$lt’=>’50']]
(โดย ‘$lt’=>’50' หมายถึง เลือกทุกค่าที่น้อยกว่า 50 )
เพิ่มเติม : https://www.mongodb.com/docs/manual/reference/operator/query/
ซึ่งเห็นภาพและเข้าใจได้ง่าย จนถึงการทำ NoSQL Authentication bypass ในเบื้องต้นด้วยครับบบ