สาเหตุของการเกิดช่องโหว่ SQL Injection

เกิดจากการที่เว็บนำข้อมูลที่ผู้ใช้ป้อน มาสั่ง Query โดยที่ไม่ได้ตรวจสอบว่าข้อมูลนั้นมีความถูกต้องเหมาะสมหรือไม่ ดังนั้น การป้องกัน SQL Injection ก็ต้องเริ่มต้นที่การตรวจสอบข้อมูลที่ได้รับมาจากผู้ใช้งานก่อนเป็นอันดับแรก โดยวิธีการที่มีประสิทธิภาพที่สุดคือ

Prepared Statements

Prepared Statements เป็นการระบุให้กับเว็บรู้ก่อนว่า ข้อมูลที่ได้รับจากผู้ใช้งานนั้นเป็น String ทั้งหมดและไม่ให้นำข้อมูลที่เป็น String เหล่านี้ ไปประมวลผลในรูปแบบของคำสั่ง SQL

//ตัวอย่างไฟล์ PHP เข้าสู่ระบบ

require 'dbcon.php'; //เรียกใช้ไฟล์ dbcon.php เพื่อใช้เชื่อมต่อฐานข้อมูล

$username = mysqli_real_escape_string($dbcon,$_POST['username']);
$password = mysqli_real_escape_string($dbcon,$_POST['password']);
//ควรใช้ mysqli_real_escape_string ในการรับค่าเสมอ กรณีที่ไม่ได้ใช้การ (Prepared Statements)

$sql = "SELECT * FROM member WHERE username =? AND password =?";

$stmt = mysqli_prepare($dbcon, $sql); 
//$dbcon คือ ตัวแปรที่ทำงานในการเชื่อมต่อฐานข้อมูล

mysqli_stmt_bind_param($stmt, "ss", $username,$password); 
//ss คือการแทนค่า ? ในตัวแปร $sql

mysqli_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$count = mysqli_num_rows($result); //นับจำนวนแถวที่ถูกส่งกลับมา

if($count == 1) 
//ถ้าจำนวนแถวที่ถูกส่งกลับมา คือ 1 (1 User) หมายความว่าทำงานถูกต้อง
{
    //การทำงานถูกต้อง
}

โดยจากในโค้ดในส่วนของการรับค่า $_POST หลายคนอาจจะสงสัยว่า ทำไมผมจึงต้องใส่ mysqli_real_escape_string ลงไป ทั้งๆที่มีการ Prepared Statements อยู่แล้ว มันจำเป็นหรือเปล่า คำตอบก็คือ จริงๆแล้ว ไม่จำเป็นต้องใส่ หากมีการ Prepared Statements อยู่แล้ว แต่ว่าเป็นนิสัยส่วนตัวของผมคือหากรับค่าจากผู้ใช้จะชอบใส่ mysqli_real_escape_string ลงไปด้วยทุกครั้ง เพื่อความปลอดภัยอะนะ 555

แล้ว mysqli_real_escape_string ทำงานยังไง?

ในกรณีที่ไม่มีได้การเขียนแบบ Prepared Statements สมมุติว่า ผู้ใช้ส่งคำสั่งนี้ไป

SELECT * FROM member WHERE username ='anny' 
AND password ='' OR username = 'anny' AND TRUE <> ''
จะกลายเป็นว่าผู้ใช้คนนั้นสามารถ Login ในนามของใครก็ได้ เพียงแค่รู้จักชื่อผู้ใช้เท่านั้นเอง (เงื่อนไขที่สองหลัง OR จะเป็นจริงเสมอ) แต่ถ้าเราใส่ mysqli_real_escape_string ลงไป จะมีการ escape ในรูปแบบนี้
SELECT * FROM member WHERE username ='anny' 
AND password ='\' OR username = 'anny' AND TRUE <> \''
ซึ่ง \' จะไม่ทำให้ SQL ผิดเพี้ยน เพราะ MySQL จะตีความเป็นเครื่องหมาย ' ให้เป็น "ข้อมูล" ไม่ใช่ "ไวยากรณ์ ของ SQL"


อ้างอิงข้อมูลบางส่วนจาก http://www.thaicreate.com, blog.wisered.com

บทความที่ถูกอ่านล่าสุด

สาเหตุของการเกิดช่องโหว่ SQL Injection และวิธีป้องกัน

สาเหตุของการเกิดช่องโหว่ SQL Injection เกิดจากการที่เว็บนำข้อมูลที่ผู้ใช้ป้อน มาสั่ง Query โดยที่ไม่ได้ตรวจสอบว่าข้อมูลนั้นมีความถูกต้องเหมาะ...

ที่อยู่: 3.233.220.21

Drive เต็มอย่างไม่รู้สาเหตุ แก้ได้ด้วย WinDirStat

หากเพื่อนกำลังประสบปัญหา Drive C หรือ Drive D เต็ม !!! โดยไม่รู้สาเหตุ ผมขอแนะนำโปรแกรม WinDirStat ที่จะทำให้เพื่อนสามารถเห็น ...

ที่อยู่: 3.233.220.21

ทำความรู้จักกับการ เข้ารหัส-ถอดรหัส แบบซีซาร์

Caesar shift เป็นเทคนิคในการเข้ารหัสแบบหนึ่ง ที่ง่ายและแพร่หลายที่สุด ตั้งแต่สมัย 50-40 ปีก่อน ค.ศ. โดยใช้หลักการแทนที่ตัวอักษร คิดค้นโดย จูเลียส ซ...

ที่อยู่: 3.233.220.21

การติดตั้ง Web Server บน Ubuntu แบบรวบรัด

สวัสดีครับ ในบทความนี้ผมจะพามาติดตั้ง Web Server บนระบบปฏิบัติการ Ubuntu (Linux) โดยจะให้สามารถทำงานร่วมกับ PHP และ MYSQL ได้ด้วย! โดยจะมีขั้นตอนดังนี้ ในการ...

ที่อยู่: 3.233.220.21

จำลองเครือข่ายคอมพิวเตอร์ ด้วย Hamachi

Hamachi เป็นโปรแกรมสำหรับเชื่อมต่อคอมพิวเตอร์ระยะไกลหลายเครื่องเข้าด้วยกัน เปรียบเสมือนวง LAN ที่อยู่บน เครือข่ายส่วนตัวเสมือน (Virtual Private Network) อี...

ที่อยู่: 3.233.220.21


บทความแนะนำ

Y2K ปัญหาใหญ่ที่เคยเกิดขึ้นกับระบบคอมพิวเตอร์โลก

ป้องกันเว็บไซต์ถูก DDoS ด้วย Cloudflare

PHP Trick: ป้องกันการถูกวาง Web Shell

ทำความรู้จักกับคอมพิวเตอร์ชนิดต่างๆ

ยอดอ่านสูงสุด

แก้ปัญหา Disk และ CPU ขึ้น 100% ใน Task manager (Windows)

Hardware

Storage


พื้นที่ว่างคงเหลือ 841.23 GB

ติดตามเราบน Facebook