ถึงเวลาคิดเรื่อง SQL INJECTION (php pdo)


หน้าแรก PHP MySQL เกร็ดความรู้ ถึงเวลาคิดเรื่อง SQL INJECTION (php pdo)
วันนี้มีโอกาสให้ได้เรียนรู้เพิ่มเติมเรื่องที่เราไม่คิด แต่จำเป็นคือเรื่อง SQL Injection หาข้อมูลอยู่พักนึงได้เรียนรู้แล้วว่า มันจำเป็นยังไงและควรทำอย่างไร

SQL Injection คืออะไร? SQL Injection ก็คือการยัดโค๊ด SQL เข้าไปตรงๆ จากรูรั่วที่เกิดขึ้น ที่เราสะเพร่า เขียนโค้ดไม่ดี เขียนมีรูรั่ว และอื่นๆ

สาเหตุการเกิด SQL INJECTION

ลองดู Code ตัวอย่างครับ ที่เราเขียนแบบเดิมๆ

รับทำเว็บ  webUB.com


ถ้า SQL ไม่มีอะไร มันจะออกมาเป็น



  Code
SELECT* FROM tbl_users WHEREid ="1"



แต่ถ้าลองมองอีกมุมนึง

ให้ $_GET['id'] เป็น " or "1"="1

ผลลัพที่ได้คือ


  Code
SELECT * FROM tbl_users WHERE id ="" or "1"="1"


โดน ยัดโค๊ด SQL เข้าไปล่ะ ”งานเข้าซะแล้ว” ผมไม่เคยอุดรูแบบนี้เลย ต่อไปนี้จะไม่มีอีกละ!!

รู้สาเหตุแล้ว มาดูวิธีป้องกัน

วิธีป้องกัน SQL INJECTION



การป้องกันก็เหมือนเดิม คือ กรอง input ถ้าหากต้องการตัวเลขก็ใช้ intvl($_GET['id']); อะไรแบบนี้
กรอง string ก็ให้ addslashes() ไป หรือใช้ mysql_real_escape_string(); ครอบ เพื่อป้องกันการใส่ ‘ หรือ ” เข้าไป
ตัวอย่าง ซักหน่อยละกัน



  Code

include "connection.php";
$id = intval($_GET['id']);
$passwd = mysql_real_escape_string($_GET['passwd']);
$sql = 'SELECT * FROM wp_users WHERE id = '.$_GET['id'].' AND passwd = "'.$passwd.'"';
echo $sql; //id จะเป็นตัวเลขละ ส่วน $passwd ก็ถูกใส่ slashes เข้าไป



แต่สำหรับผม ผมชอบใช้ PDO ซึ่งชัวน่าจะ 100% เต็มในการป้อง SQL Injection (ลองแล้วๆ)
โดย PDO จะมี method prepare เพื่อที่จะ bindParam ก่อน execute ได้ ตัวอย่างเช่น



  Code
$db = new PDO('mysql:host=localhost;dbname=mydb','root','1234');
$stmt = $db->prepare('SELECT * FROM tbl_users WHERE id = :id AND password = :password LIMIT 1');
$stmt->bindParam(':id',$_GET['id'],PDO::PARAM_INT);
$stmt->bindParam(':id',$_GET['passwd'],PDO::PARAM_STR,32);
$stmt->execute();



PDO จะจัดการให้เรียบร้อย

และสำหรับ PDO ยังมี method quote ไว้ใช้ คล้ายกับ mysql_real_escape_string กรณีที่ต้องการความว่องไว (ขี้เกียจว่างั้น)



  Code
$db = new PDO('mysql:host=localhost;dbname=mydb','root','1234');
$stmt = $db->query('SELECT * FROM tbl_user WHERE username = '.$db->quote($_GET['user']).' LIMIT 1');
if($stmt)
while($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
//....
}



ขอบคุณ Expert Duck ที่ให้ความรู้ด้านนี้ครับ

ขึ้นไปด้านบน