มีอยู่วันหนึ่ง เว็บลูกค้าที่ผมดูแลอยู่เกิดผิดปรกติ เมื่อเข้าไปดูปรากฏว่าไฟล์บนเว็บถูกลบ แล้วเปลี่ยนเป็นข้อความว่าเว็บนี้โดนแฮ็คแล้ว
ความคิดแรกที่สงสัยคือ โน๊ตบุคของเราติดไวรัส โดนดักจับรหัสผ่านหรือเปล่า
ทำให้แฮ็กเกอร์รู้รหัสผ่าน แล้วเข้าไปแก้ไขเว็บของเรา
หลังจากอ่านข้อมูลในอินเตอร์เน็ต จึงพบว่า การถูกแฮ็คครั้งนี้เกิดจาก SQL Injection
แล้วอะไรคือ SQL Injection ?
สมมุติหน้าเว็บใช้ชื่อไฟล์ว่า articles_view.php?id=1
และในไฟล์ articles_view.php มี code เขียนว่า
$sql = "select * from articles where id = '$id' ";
ผู้ไม่หวังดีแอบส่งค่าเป็น articles_view.php?id=1'or'1=1
ก็จะสามารถเรียกดูข้อมูลใน database ของเราได้ทั้งหมด
(รายละเอียดวิธีทำ ไปหาอ่านใน google เองนะครับ)
วิธีป้องกัน ผมใช้ code นี้ แปะไว้ส่วนบนของไฟล์ php ทุกไฟล์
# ป้องกัน sql injection จาก $_GET
foreach ($_GET as $key => $value) {
$_GET[$key]=addslashes(strip_tags(trim($value)));
}
if ($_GET['id'] !='') { $_GET['id']=(int) $_GET['id']; }
extract($_GET);
บรรทัดที่ 2 หมายความว่า ทุกๆค่าที่ถูกส่งมาด้วยการ GET ให้ตัดช่องว่างด้านหน้าและด้านหลัง
แล้วตัดเครื่องหมาย html ออก
คำสั่ง strip_tags นี้ช่วยให้ การแทรก code javascipt ทำงานผิดพลาด
เช่นมีคนแทรก javascript มาว่า <script>alert('555');</script>
คำสั่ง strip_tags จะทำเหลือแต่ข้อความ alert('555') ซึ่งทำงานไม่ได้ เพราะไม่ได้ระบุว่าเป็น javascript
หลังจากนั้นก็ addslashes เข้าไปอีกชั้นนึง ถ้ามีคนส่งค่า 1'or'1=1 เข้ามา จะถูกแปลงเป็น 1\'or\'1=1
ทำให้คำสั่ง SQL ล้มเหลว ประมวลผลผิด
และตบท้ายด้วยการเช็คค่า id ถ้าไม่ใช่ช่องว่าง ให้แปลง id เป็น integer เท่านั้น
และปิดด้วยคำสั่ง extract($_GET) เพื่อรับค่าจากการ GET ทั้งหมด
วิธีนี้ป้องกัน SQL Injection จากทุกหน้าที่รับค่าด้วยการ GET
ส่วนหน้าไหนที่มี form submit รับค่าจากการ POST ก็ใช้หลักการเดียวกัน
ยังมีอีกส่วนที่เราต้องป้องกัน คือ การกรอก user, password
ตัวแปรที่รับค่าจะต้อง addslashes เข้าไปด้วย เช่น
$username = addslashes(trim($_POST['user']));
$password= addslashes(trim($_POST['pwd']));
ถึงตรงนี้ เราคิดว่าเราป้องกันดีแล้วทั้งจาก GET และ POST
แต่ยังมีอีกส่วนหนึ่ง สมมติเรามี webboard ที่อนุญาติให้คนทั่วไปอัพรูปเข้ามาได้
แล้วเรามีหน้า admin ซึ่งตั้งค่าได้ว่า จะอนุญาติให้อัพไฟล์ชนิดใดได้บ้าง
แล้วแฮ็กเกอร์เก่งมาก เดา user, password ถูก เข้าสู่หน้า admin ของเราได้
แล้วไปแก้การอนุญาติอัพโหลดไฟล์ ให้อนุญาติไฟล์ .php ด้วย
จากนั้นก็อัพไฟล์ .php ของแฮ็คเกอร์ขึ้นเว็บเรา
หลังจากนั้น แฮ็กเกอร์ก็จะสามารถจัดการ อัพโหลด ดาวโหลด สั่งลบ ทุกไฟล์ในเว็บเราได้
การป้องกันอีกชั้นนึง คือ ต้องไม่อนุญาติให้อัพโหลดไฟล์ .php อย่างเด็ดขาด
ผมใช้ code นี้ในการตรวจสอบการอัพโหลดไฟล์ผ่าน webboard
$filename=$_FILES[$namefile]['name'];
$u1=substr($filename, -3); $u1=strtolower($u1);
// รายชื่อชนิดไฟล์ที่อนุญาติ ที่บันทึกไว้ในฐานข้อมูล
$allowfile=' '.$setting["allow_file"];
// แม้ว่าในฐานข้อมูลจะอนุญาติไฟล์ .php แต่ในขั้นตอนอัพโหลด เราจะยกเลิกไฟล์ php
$u3='php,htm,.pl,cgi,js,asp,swf,com,bat,cmd';
$t1=explode(',', $u3); $len=count($t1);
for ($i=0; $i<$len; $i++) {
$allowfile=str_replace($t1[$i], '', $allowfile);
}
if (strpos($allowfile, $u1) == 0 ) alertBack("ไม่อนุญาติให้อัพโหลดไฟล์ชนิดนี้");
จนถึงตรงนี้ คิดว่าป้องกันดีที่สุดแล้ว แต่ถ้าโดนอีก ก็ค่อยศึกษาใน google อีกทีนึง
ดีกว่าเราไม่รู้ และไม่ป้องกันอะไรเลย
17 ม.ค. 57