SQLite - การฉีด
หากคุณรับข้อมูลผู้ใช้ผ่านหน้าเว็บและแทรกลงในฐานข้อมูล SQLite มีโอกาสที่คุณจะเปิดกว้างสำหรับปัญหาด้านความปลอดภัยที่เรียกว่า SQL Injection ในบทนี้คุณจะได้เรียนรู้วิธีช่วยป้องกันไม่ให้สิ่งนี้เกิดขึ้นและช่วยคุณรักษาความปลอดภัยสคริปต์และคำสั่ง SQLite ของคุณ
การฉีดมักเกิดขึ้นเมื่อคุณขอให้ผู้ใช้ป้อนข้อมูลเช่นชื่อของพวกเขาและแทนที่จะเป็นชื่อพวกเขาให้คำสั่ง SQLite กับคุณซึ่งคุณจะเรียกใช้ฐานข้อมูลของคุณโดยไม่รู้ตัว
อย่าเชื่อถือข้อมูลที่ผู้ใช้ให้มาประมวลผลข้อมูลนี้หลังจากการตรวจสอบแล้วเท่านั้น ตามกฎแล้วสิ่งนี้ทำได้โดยการจับคู่รูปแบบ ในตัวอย่างต่อไปนี้ชื่อผู้ใช้ถูก จำกัด ไว้ที่ตัวอักษรและตัวเลขคละกันบวกขีดล่างและมีความยาวระหว่าง 8 ถึง 20 ตัวอักษร - แก้ไขกฎเหล่านี้ได้ตามต้องการ
if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)){
$db = new SQLiteDatabase('filename');
$result = @$db->query("SELECT * FROM users WHERE username = $matches[0]");
} else {
echo "username not accepted";
}
เพื่อแสดงให้เห็นถึงปัญหาให้พิจารณาข้อความที่ตัดตอนมานี้ -
$name = "Qadir'; DELETE FROM users;";
@$db->query("SELECT * FROM users WHERE username = '{$name}'");
การเรียกใช้ฟังก์ชันควรจะดึงข้อมูลจากตารางผู้ใช้โดยที่คอลัมน์ชื่อตรงกับชื่อที่ผู้ใช้ระบุ ภายใต้สถานการณ์ปกติ$nameจะมีเพียงอักขระที่เป็นตัวเลขและตัวอักษรและอาจเว้นวรรคเช่นสตริง ilia อย่างไรก็ตามในกรณีนี้การต่อท้ายคำค้นหาใหม่ทั้งหมดกับ $ name การเรียกไปยังฐานข้อมูลจะกลายเป็นหายนะ: แบบสอบถาม DELETE ที่ถูกแทรกจะลบบันทึกทั้งหมดจากผู้ใช้
มีอินเทอร์เฟซฐานข้อมูลที่ไม่อนุญาตให้มีการซ้อนคิวรีหรือเรียกใช้การสืบค้นหลายรายการในการเรียกฟังก์ชันเดียว หากคุณพยายามซ้อนคิวรีการเรียกจะล้มเหลว แต่ SQLite และ PostgreSQL ดำเนินการแบบสอบถามแบบเรียงซ้อนกันอย่างมีความสุขดำเนินการค้นหาทั้งหมดที่มีให้ในสตริงเดียวและสร้างปัญหาด้านความปลอดภัยที่ร้ายแรง
การป้องกัน SQL Injection
คุณสามารถจัดการอักขระ Escape ทั้งหมดได้อย่างชาญฉลาดในภาษาสคริปต์เช่น PERL และ PHP ภาษาการเขียนโปรแกรม PHP ให้ฟังก์ชันstring sqlite_escape_string() เพื่อหลีกเลี่ยงอักขระอินพุตที่พิเศษสำหรับ SQLite
if (get_magic_quotes_gpc()) {
$name = sqlite_escape_string($name);
}
$result = @$db->query("SELECT * FROM users WHERE username = '{$name}'");
แม้ว่าการเข้ารหัสจะทำให้สามารถแทรกข้อมูลได้อย่างปลอดภัย แต่ก็จะแสดงผลการเปรียบเทียบข้อความอย่างง่ายและ LIKE คำสั่งในการสืบค้นของคุณใช้ไม่ได้สำหรับคอลัมน์ที่มีข้อมูลไบนารี
Note - addslashes()ไม่ควรใช้เพื่ออ้างสตริงของคุณสำหรับการสืบค้น SQLite ซึ่งจะนำไปสู่ผลลัพธ์ที่แปลกประหลาดเมื่อดึงข้อมูลของคุณ