1. การโจมตีแบบฉีด SQL คืออะไร?
การโจมตีแบบแทรก SQL หมายความว่าผู้โจมตีแทรกคำสั่ง SQL ลงในช่องป้อนข้อมูลของฟอร์มเว็บหรือสตริงการสืบค้นของคำขอเพจ และหลอกลวงเซิร์ฟเวอร์ให้ดำเนินการคำสั่ง SQL ที่เป็นอันตราย ในบางรูปแบบ การป้อนข้อมูลของผู้ใช้จะถูกใช้โดยตรงเพื่อสร้าง (หรือส่งผลกระทบ) คำสั่ง SQL แบบไดนามิก หรือเป็นพารามิเตอร์อินพุตสำหรับขั้นตอนการจัดเก็บ แบบฟอร์มดังกล่าวมีความเสี่ยงเป็นพิเศษต่อการโจมตีแบบ SQL Inject กระบวนการโจมตีการแทรก SQL ทั่วไปประกอบด้วย:
⑴ เว็บแอปพลิเคชัน ASP.NET มีหน้าเข้าสู่ระบบ หน้าเข้าสู่ระบบนี้จะควบคุมว่าผู้ใช้มีสิทธิ์ในการเข้าถึงแอปพลิเคชันหรือไม่
⑵ เนื้อหาที่ป้อนในหน้าเข้าสู่ระบบจะถูกใช้โดยตรงเพื่อสร้างคำสั่ง SQL แบบไดนามิก หรือใช้เป็นพารามิเตอร์ของขั้นตอนการจัดเก็บโดยตรง นี่คือตัวอย่างของแอปพลิเคชัน ASP.NET ที่สร้างแบบสอบถาม:
System.Text.StringBuilder query = new System.Text.StringBuilder(
"เลือก * จากผู้ใช้โดยที่เข้าสู่ระบบ = '")
.ผนวก(txtLogin.Text).ผนวก("' และรหัสผ่าน='")
.ผนวก(txtPassword.Text).ผนวก("'");
⑶ ผู้โจมตีป้อนข้อมูลเช่น "' หรือ '1'='1" ในช่องชื่อผู้ใช้และรหัสผ่าน
⑷ หลังจากที่ผู้ใช้ส่งเนื้อหาที่ป้อนไปยังเซิร์ฟเวอร์ เซิร์ฟเวอร์จะรันโค้ด ASP.NET ข้างต้นเพื่อสร้างคำสั่ง SQL เพื่อสอบถามผู้ใช้ อย่างไรก็ตาม เนื่องจากเนื้อหาที่ผู้โจมตีป้อนนั้นมีความพิเศษมาก คำสั่ง SQL สุดท้าย กลายเป็น: SELECT * จากผู้ใช้ WHERE เข้าสู่ระบบ = '' หรือ '1'='1' และรหัสผ่าน = '' หรือ '1'='1'
⑸ เซิร์ฟเวอร์ดำเนินการค้นหาหรือกระบวนการที่เก็บไว้เพื่อเปรียบเทียบข้อมูลประจำตัวที่ป้อนโดยผู้ใช้กับข้อมูลประจำตัวที่บันทึกไว้ในเซิร์ฟเวอร์
⑹ เนื่องจากคำสั่ง SQL ได้รับการแก้ไขจริงโดยการโจมตีแบบฉีด และไม่สามารถตรวจสอบตัวตนของผู้ใช้ได้อย่างแท้จริง ระบบจึงให้สิทธิ์ผู้โจมตีไม่ถูกต้อง
หากผู้โจมตีรู้ว่าแอปพลิเคชันจะใช้เนื้อหาที่ป้อนในแบบฟอร์มโดยตรงเพื่อสอบถามการยืนยันตัวตน เขาจะพยายามป้อนสตริง SQL พิเศษบางอย่างเพื่อแก้ไขแบบสอบถามเพื่อเปลี่ยนฟังก์ชันการทำงานดั้งเดิมและหลอกให้ระบบให้สิทธิ์การเข้าถึง
ทั้งนี้ขึ้นอยู่กับสภาพแวดล้อมของระบบ ความเสียหายที่ผู้โจมตีอาจก่อให้เกิดจะแตกต่างกันไป ซึ่งส่วนใหญ่จะถูกกำหนดโดยการอนุญาตด้านความปลอดภัยของแอปพลิเคชันในการเข้าถึงฐานข้อมูล หากบัญชีของผู้ใช้มีผู้ดูแลระบบหรือสิทธิ์ขั้นสูงอื่นๆ ผู้โจมตีอาจดำเนินการต่างๆ ในตารางฐานข้อมูลที่เขาต้องการ รวมถึงการเพิ่ม ลบ หรืออัปเดตข้อมูล หรือแม้แต่การลบตารางโดยตรง
2.ป้องกันอย่างไร?
โชคดีที่การป้องกันแอปพลิเคชัน ASP.NET จากการถูกโจมตีโดยการฉีด SQL นั้นไม่ใช่เรื่องยาก สิ่งที่คุณต้องทำคือกรองเนื้อหาอินพุตทั้งหมดก่อนที่จะใช้เนื้อหาอินพุตของฟอร์มเพื่อสร้างคำสั่ง SQL การกรองอินพุตสามารถทำได้หลายวิธี
⑴ สำหรับสถานการณ์ที่มีการสร้างการสืบค้น SQL แบบไดนามิก สามารถใช้เทคนิคต่อไปนี้:
ขั้นแรก: แทนที่เครื่องหมายคำพูดเดี่ยว นั่นคือ เปลี่ยนเครื่องหมายคำพูดเดี่ยวทั้งหมดเป็นสองเครื่องหมายคำพูดเดี่ยว เพื่อป้องกันไม่ให้ผู้โจมตีแก้ไขความหมายของคำสั่ง SQL ดูตัวอย่างก่อนหน้านี้อีกครั้ง "SELECT * from Users WHERE login = ''' or ''1''=''1' ANDpassword = ''' or ''1''=''1'" จะได้รับอย่างชัดเจน ผลลัพธ์เดียวกัน "SELECT * from Users WHERE login = '' or '1'='1' ANDpass = '' or '1'='1'"
ประการที่สอง: ลบยัติภังค์ทั้งหมดในเนื้อหาที่ผู้ใช้ป้อนเพื่อป้องกันไม่ให้ผู้โจมตีสร้างคำสั่งเช่น "SELECT * จากผู้ใช้ WHERE เข้าสู่ระบบ = 'mas' -- AND รหัสผ่าน =''" เนื่องจากส่วนต่อท้ายของแบบสอบถามดังกล่าวได้รับการแสดงความคิดเห็นครึ่งหนึ่ง ออกและไม่สามารถใช้ได้อีกต่อไป ผู้โจมตีจำเป็นต้องทราบชื่อเข้าสู่ระบบของผู้ใช้ที่ถูกกฎหมายเท่านั้น และไม่จำเป็นต้องทราบรหัสผ่านของผู้ใช้จึงจะเข้าถึงได้สำเร็จ
ประการที่สาม: จำกัดสิทธิ์ของบัญชีฐานข้อมูลที่ใช้ในการดำเนินการสืบค้น ใช้บัญชีผู้ใช้ที่แตกต่างกันเพื่อดำเนินการสอบถาม แทรก อัปเดต และลบ โดยการแยกการดำเนินการที่สามารถทำได้โดยบัญชีต่างๆ จะป้องกันไม่ให้สถานที่เดิมที่ใช้ในการดำเนินการคำสั่ง SELECT ถูกใช้เพื่อดำเนินการคำสั่ง INSERT, UPDATE หรือ DELETE
⑵ ใช้ขั้นตอนการจัดเก็บเพื่อดำเนินการค้นหาทั้งหมด วิธีส่งพารามิเตอร์ SQL จะป้องกันไม่ให้ผู้โจมตีใช้เครื่องหมายคำพูดเดี่ยวและยัติภังค์เพื่อทำการโจมตี นอกจากนี้ ยังอนุญาตให้จำกัดสิทธิ์ของฐานข้อมูลเพื่อดำเนินการเฉพาะขั้นตอนการจัดเก็บเฉพาะเท่านั้น การป้อนข้อมูลของผู้ใช้ทั้งหมดจะต้องสอดคล้องกับบริบทด้านความปลอดภัยของขั้นตอนการจัดเก็บที่เรียกว่า ดังนั้นการโจมตีแบบฉีดจึงเกิดขึ้นได้ยาก
⑶ จำกัดความยาวของฟอร์มหรืออินพุตสตริงการสืบค้น หากชื่อเข้าสู่ระบบของผู้ใช้มีอักขระได้สูงสุด 10 ตัว อย่ายอมรับอักขระที่ป้อนเกิน 10 ตัวในแบบฟอร์ม ซึ่งจะเพิ่มความยากสำหรับผู้โจมตีในการแทรกโค้ดที่เป็นอันตรายลงในคำสั่ง SQL
⑷ ตรวจสอบความถูกต้องตามกฎหมายของอินพุตของผู้ใช้ และตรวจสอบให้แน่ใจว่าเนื้อหาอินพุตมีเฉพาะข้อมูลทางกฎหมายเท่านั้น การตรวจสอบข้อมูลควรทำทั้งฝั่งไคลเอ็นต์และเซิร์ฟเวอร์ - ทำการตรวจสอบฝั่งเซิร์ฟเวอร์เพื่อชดเชยความปลอดภัยที่เปราะบางของกลไกการตรวจสอบฝั่งไคลเอ็นต์
ในฝั่งไคลเอ็นต์ ผู้โจมตีสามารถรับซอร์สโค้ดของหน้าเว็บ แก้ไขสคริปต์ที่ตรวจสอบความถูกต้องตามกฎหมาย (หรือลบสคริปต์โดยตรง) จากนั้นส่งเนื้อหาที่ผิดกฎหมายไปยังเซิร์ฟเวอร์ผ่านแบบฟอร์มที่แก้ไข ดังนั้นวิธีเดียวที่จะให้แน่ใจว่ามีการดำเนินการตรวจสอบจริงคือทำการตรวจสอบทางฝั่งเซิร์ฟเวอร์ด้วย คุณสามารถใช้ออบเจ็กต์การตรวจสอบความถูกต้องในตัวได้มากมาย เช่น RegularExpressionValidator ซึ่งสามารถสร้างสคริปต์ฝั่งไคลเอ็นต์สำหรับการตรวจสอบได้โดยอัตโนมัติ และแน่นอนว่า คุณยังสามารถแทรกการเรียกเมธอดฝั่งเซิร์ฟเวอร์ได้อีกด้วย หากคุณไม่พบออบเจ็กต์การตรวจสอบสำเร็จรูป คุณสามารถสร้างออบเจ็กต์การตรวจสอบได้ด้วยตนเองผ่าน CustomValidator
⑸ เข้ารหัสและบันทึกชื่อล็อกอินของผู้ใช้ รหัสผ่าน และข้อมูลอื่น ๆ การเข้ารหัสข้อมูลที่ป้อนโดยผู้ใช้แล้วเปรียบเทียบกับข้อมูลที่บันทึกไว้ในฐานข้อมูลจะเทียบเท่ากับการ "ฆ่าเชื้อ" ข้อมูลที่ผู้ใช้ป้อน ข้อมูลที่ป้อนโดยผู้ใช้จะไม่มีความหมายพิเศษใดๆ ต่อฐานข้อมูลอีกต่อไป ดังนั้นจึงเป็นการป้องกัน ผู้โจมตีจากการฉีดคำสั่ง SQL คลาส System.Web.Security.FormsAuthentication มี HashPasswordForStoringInConfigFile ซึ่งเหมาะมากสำหรับการฆ่าเชื้อข้อมูลอินพุต
⑹ ตรวจสอบจำนวนบันทึกที่ส่งคืนโดยการสืบค้นที่ดึงข้อมูล หากโปรแกรมต้องการเพียงหนึ่งระเบียนที่จะส่งคืน แต่ระเบียนที่ส่งคืนจริงมีมากกว่าหนึ่งแถว จะถือว่าเป็นข้อผิดพลาด