ข้ามไปที่เนื้อหาหลัก

PHP การล็อกอิน กับปัญหา SQL Injection

       หลังจากได้เข้าร่วมอบรม Website Security Monitoring ที่ทางสำนักวิทยบริการและเทคโนโลยีสารสนเทศ ของมหาวิทยาลัยจัดขึ้น ก็ได้ความรู้เรื่องการสร้างระบบล็อกอินเพื่อป้องกันปัญหา SQL Injection มาฝากกับผู้เริ่มต้นทุกท่าน
สำหรับการป้องกันนั้นจะมีอยู่หลายวิธี และวิธีหลักที่ใช้กันก็คือ
กรองด้วยฟังก์ชั่น mysql_real_escape_string() , mysqli_real_escape_string() ,
(ดูเพิ่มเติมได้ที่ http://php.net/manual/en/function.mysql-real-escape-string.php )

ในกรณีของ id ที่เป็นตัวเลขล้วน ก็สามารถใช้ (int) วางไว้ข้างหน้าตัวแปรเพื่อป้องกันข้อมูลในหน้าอื่นๆได้เช่นกัน

แต่ในตัวอย่างของบทความนี้ จะอธิบายทีละส่วนเพื่อให้เห็นถึงวิธีการต่างๆ ที่จะโยงไปยังเรื่องของการใช้ md5 ในบทความต่อๆไปด้วยครับ

จากบทความที่เคยนำเสนอเกี่ยวกับการสร้างแบบฟอร์มล็อกอิน
จะใช้ SQL ในการตรวจสอบข้อมูลแบบเบื้องต้นดังนี้
$sql = "SELECT * FROM tb_user WHERE user_name = '$_POST[username]'
           AND user_password = '". $_POST['password'] ."' ";

ตัวอย่างฐานข้อมูลตารางผู้ใช้งาน


ฐานข้อมูล ตาราง ผู้ใช้งาน



เมื่อล็อกอินด้วยชื่อ sunzandesign และรหัสผ่าน abcd จะสามารถเข้าใช้งานได้

php login form

ก็จะได้ผลลัพธ์การล็อกอิน ดังนี้

php login corect



แต่ถ้าเรากรอกชื่อผู้ใช้งานผิด การล็อกอินก็จะแสดงข้อผิดพลาด และให้ล็อกอินใหม่

result login incorect


สังเกตว่าเรากรอกรหัสผ่านว่า admin ก็จะถูกนำไปสร้าง SQL สำหรับคิวรี่เรียกข้อมูลจากฐานข้อมูลตรงๆ ดังนั้นการที่เราจะแฮกเข้าไปในยูสเซอร์ที่เราต้องการ ก็เพียงแค่ใช้ชื่อยูสเซอร์ sunzandesign และรหัสอะไรก็ได้ ตามด้วย OR เพื่อให้แทรกลงไปใน SQL ให้เกิดการทำงานในแบบที่เราต้องการ

ตัวอย่างเช่น
ชื่อผู้ใช้ = sunzandesign
รหัสผ่าน = xxxx' OR 'A'='A


login with sql injection


ผลลัพธ์ที่ได้คือ ล็อกอินผ่าน!!! เพราะอะไร???
เพราะเราเพิ่มเงื่อนไขเข้าไปคือ นอกจากชื่อรหัสผ่านต้องตรงกับฐานข้อมูลแล้ว
OR 'A' = 'A' ถ้า A มีค่าเท่ากับ A ก็ให้ผ่านไปได้  ((ซึ่งมันก็ต้องตรงกันอยู่วันยังค่ำ = ='))


result is corect by sql injection
ถ้าลองนำโค๊ดที่ได้ไปลองใน phpMyAdmin จะได้ผลลัพธ์ดังนี้

result in phpmyadmin with sql injection


ตอนนี้ก็ทราบกันแล้วว่า SQL แบบที่นำเสนอไปนั้นไม่สามารถใช้กับระบบล็อกอินได้เลย
((รวมถึงหน้าอื่นๆทุกหน้าที่เขียน SQL แบบธรรมดาที่ไม่มีการป้องกันแบบตัวอย่างนี้ ล้วนเป็นช่องโหว่ทั้งหมด >O< ))


แล้วเราจะมีวิธีป้องกัน SQL injection อย่างไร???


ก็ใช้ฟังก์ชั่นดังที่ได้แนะนำไว้ก่อนหน้านี้นั่นก็คือ
ในกรณีรับข้อมูลที่เป็น string (หรือจะเป็น integer ก็ได้)
mysql_real_escape_string()
mysqli_real_escape_string() 



  $sql = "SELECT * FROM tb_user
            WHERE user_name = '". mysql_real_escape_string($_POST['username']) ."'
            AND user_password = '". mysql_real_escape_string($_POST['password']) ."' ";
fix SQL Injection with mysql_real_escape_string


หรือจะใช้วิธี md5() รหัสผ่านไปเลยก็ได้(ซึ่งจริงๆแล้วรหัสผ่านก็ควรจะเข้ารหัสไว้แล้ว) โค๊ดที่ใช้ก็จะเปลี่ยนไปเป็นดังนี้
  $sql = "SELECT * FROM tb_user
            WHERE user_name = '". $_POST['username'] ."'
            AND user_password = '". md5($_POST['password']) ."' ";


ก่อนอื่นก็เข้ารหัสให้กับรหัสผ่านเดิมทั้งหมดในฐานข้อมูลก่อน ก็จะได้ข้อมูลดังภาพ
password with md5 data

ทดลองกรอกข้อมูลที่ถูกต้องในการล็อกอินเพื่อทดสอบ
login with md5 password


จะได้ผลลัพธ์ที่ถูกต้อง
login is corect by md5()
abcd => md5() => e2fc714c4727ee9395f324cd2e7f331f
((ตรงกับข้อมูลในฐานข้อมูล))


แต่ถ้าลองกรอกข้อมูลเพื่อใช้เทคนิค SQL Injection ก็จะไม่สามารถล็อกอินได้
test login with sql injection

login is fail by sql injection

เพราะข้อมูลรหัสผ่านไม่ตรงกับในฐานข้อมูล

xxxx' OR 'A'='A => md5() => c47fef686224b37f5f3350dfae45ca15
((ไม่ตรงกับข้อมูลในฐานข้อมูล))


และวิธีสุดท้ายที่จะนำเสนอในบทความนี้ หากท่านไม่สามารถใช้งาน mysql_real_escape_string() และไม่พร้อมที่ md5() รหัสผ่าน (หรือเข้ารหัสผ่านแบบอื่นๆ) ให้ลองใช้วิธีแยกรหัสผ่านมาตรวจสอบต่างหากด้วยฟังก์ชั่น if else ของ PHP

    $sql = "SELECT user_password FROM tb_user
            WHERE user_name = '". $_POST['username'] ."'";
      $qry = mysql_query($sql) or die(mysql_error());
      $row = mysql_fetch_assoc($qry);
      if(!empty($row) && $row['user_password'] == $_POST['password']){
        echo "<h3 style='color:green'>Login OK!</h3>";
      }else{
        echo "<h3 style='color:red'>Login Fail!</h3>";
     }







"PHP ไม่ได้สร้างสุดยอดโปรแกรม แต่ PHP ช่วยให้งานคุณง่ายขึ้นต่างหาก"

PHP CI MANIA PHP Code Generator 
โปรแกรมช่วยสร้างโค้ด ลดเวลาการเขียนโปรแกรม

สนใจสั่งซื้อเพียง 4,500 บาท
http://fastcoding.phpcodemania.com/

สนับสนุนค่ากาแฟผู้เขียนได้ที่

PayPal

ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

แจกฟรี!! ระบบต่างๆที่พัฒนาด้วย PHP สำหรับนำไปใช้ในงานต่างๆ

       สำหรับหลายท่านที่ขอโค้ดเข้ามาทาง Inbox ของเฟซบุ๊กแฟนเพจ หรือถามถึงระบบต่างๆหลังไมค์มานั้น ส่วนใหญ่ก็มีแจกอยู่แล้วในเว็บบอร์ด ThaiCreate.Com นะครับ และด้านล่างนี้ก็เป็นระบบต่างๆที่แจกให้นำไปลองใช้ลองศึกษากันครับ

สร้างแบบฟอร์มล็อกอิน HTML + PHP

       ผมจะสร้างระบบตัวอย่างเพื่อแสดงให้เห็นการทำงานของสคริปต์ PHP ที่ใช้ในการล็อกอินอย่างง่ายๆ นะครับ โดยที่ผมจะสร้างโฟลเดอร์ใหม่ขึ้นในไดร์ฟที่เราได้กำหนดให้เป็น Directory Root สำหรับรันสคริปต์ PHP ซึ่งผมกำหนดเอาไว้ที่ D:\www ดังนั้นผมจะสร้างโฟลเดอร์ teacher_assistant ขึ้นมาใหม่จะได้พาธเป็น D:\www\teacher_assistant สำหรับการเข้าถึง จะใช้ URL ดังนี้ http://localhost/teacher_assistant หลังจากสร้างโฟลเดอร์เสร็จเรียบร้อยก็จะเริ่มกระบวนการเตรียมโครงสร้างโปรเจ็กต์ด้วยเครื่องมือช่วยเขียนโปรแกรมชื่อว่า eclipse ซึ่งดูวิธีการสร้างโปรเจ็กต์ได้จากบทความ เริ่มต้นสร้างโปรเจ็กต์ ด้วยโปรแกรม eclipse เครื่องมือเขียนโปรแกรม php ในบทความเป็นการสร้างโปรเจ็กต์ที่มีพาธเป็นโฟลเดอร์ login แต่ในที่นี้ต้องเป็นพาธให้ตรงกับโฟลเดอร์ใหม่ที่เราได้สร้างขึ้นด้วยนะครับ

PHP กับการคิดส่วนลดเป็นเปอร์เซ็น 5%, 10%, 20% ตามช่วงราคาที่กำหนด

<?php     $total_price = 1000;     $discount = 0;         if($total_price >= 500 && $total_price < 1001){         $discount = 5;     }elseif($total_price >= 1001 && $total_price <= 5000){         $discount = 10;     }elseif($total_price >= 5001){         $discount = 20;     }         $discount_bath = ($total_price*$discount)/100; ?> <pre> ซื้อสินค้าครบ 0 ถึง 499 บาท ไม่ได้ส่วนลด ซื้อสินค้าครบ 500 ถึง 1000 บาท ได้ส่วนลด 5% ซื้อสินค้าครบ 1001 ถึง 5000บาท ได้ส่วนลด 10% ซื้อสินค้าครบ 5001 บาทขึ้นไป ได้ส่วนลด 20% </pre> <h3>รวมราคาสินค้า = <?php echo number_format($total_price,2);?></h3> <h5>ส่วนลด = <?php echo $discount;?>%  (<?php echo $discount_bath;?> บาท)</h5> <h2>ราคาหลังส่วนลด = <?php echo number_format($total_price - $discount_bath,2);?>บาท</h2> "PHP ไม่ได้สร้างสุดยอดโปรแกรม แต่ PHP ช่วยให้งานคุณง่ายขึ้นต