แม้ปัญหาความปลอดภัยจะเริ่มต้นในยุคแรกๆ ในโลกด้วยปัญหา buffer overflow แต่เมื่อโลกเข้าสู่ยุคของเว็บ และโดยเฉพาะเมื่อเว็บเริ่มไม่ใช่ไฟล์ html เปล่าๆ แต่เป็นเว็บที่สามารถปรับตามผู้ใช้งานได้ เริ่มจากยุคของ CGI ที่เป็นโปรแกรมภาษาต่างๆ เรื่อยมาถึงเว็บเซิร์ฟเวอร์แบบอื่นไม่ว่าจะเป็น J2EE หรือระบบ fastcgi ปัญหาความปลอดภัยของเว็บก็กลายเป็นปัญหาใหญ่ที่โลกเจอกันเรื่อยมาจนทุกวันนี้
ปัญหา script injection หรือการใส่สคริปต์เข้ามาในเซิร์ฟเวอร์นั้นเป็นการโจมตีที่ตรงตัวกับชื่อของมัน เมื่อเซิร์ฟเวอร์เปิดให้อัพโหลดไฟล์เข้าไปยังเซิร์ฟเวอร์ ไม่ว่าจะเป็นการอัพโหลดภาพ หรือการอัพโหลดไฟล์อื่นๆ ในเว็บเซิร์ฟเวอร์ที่รันไฟล์ภาษาสคริปต์นั้น โดยทั่วไปแล้วจะถูกคอนฟิกให้รันทุกไฟล์สคริปต์ เช่น เว็บเซิร์ฟเวอร์ Apache ที่ติดตั้ง PHP ทุกวันนี้จะถูกคอนฟิกให้รันทุกไฟล์ที่ลงท้ายชื่อไฟล์ด้วย ".php"
เว็บแอพพลิเคชั่นที่ไม่ระมัดระวังเพียงพอจะปล่อยให้มีการอัพโหลดชื่อไฟล์ที่ตรงตามเงื่อนไขของสคริปต์ ส่งผลให้แฮกเกอร์สามารถส่งไฟล์ใดๆ ขึ้นมารันบนเครื่อง และเมื่อรันแล้วจะได้สิทธิเท่ากับเว็บเซิร์ฟเวอร์ทุกประการ เช่น การอ่านไฟล์ทั้งหมด, การอ่านฐานข้อมูล (เพราะสามารถอ่านไฟล์คอนฟิกของเว็บแอพพลิเคชั่นได้) จนกระทั่งในเซิร์ฟเวอร์รุ่นเก่าๆ นั้น นิยมตั้งให้เว็บเซิร์ฟเวอร์ทำงานในฐานะผู้ใช้ root จะส่งผลให้การเผอเรอเพียงการปล่อยให้ผู้ใช้อัพโหลดไฟล์โดยไม่ตรวจสอบเพียงจุดเดียวสร้างความเสียหายได้อย่างมาก
ระบบจัดการเนื้อหารุ่นใหม่ๆ เมื่อมีส่วนใดที่ต้องรับไฟล์อัพโหลดจากผู้ใช้ มักจะจัดให้อยู่ในโฟลเดอร์เดียวกันทั้งหมด พร้อมกับตรวจสอบชื่อไฟล์ว่าไม่มีชื่อไฟล์ใดที่จะสามารถรันได้ เช่น การจำกัดชื่อไฟล์ให้รับเฉพาะไฟล์ที่ไม่สามารถรันได้ เช่นไฟล์ PNG, JPG หรือ PDF ใน กระบวนการรักษาความปลอดภัยจึงอาจจะทำได้โดยการคอนฟิกยกเลิกไม่ให้เว็บเซิร์ฟเวอร์รันสคริปต์ใดๆ ในโฟลเดอร์ที่ใช้สำหรับการรับไฟล์อัพโหลด และหากต้องการเพิ่มประเภทไฟล์ที่รับอัพโหลด ควรระวังไม่รับไฟล์ที่สามารถรันบนเซิร์ฟเวอร์ได้ เช่น สคริปต์ภาษาต่างๆ รวมถึงภาษาที่อาจจะไม่ได้ใช้งาน อย่างภาษา Perl (.pl)
นอกจากการอัพโหลดไฟล์แล้ว หลายครั้งสคริปต์ในการรันนั้นมีการนำอินพุตของผู้ใช้ไปเชื่อมกับสตริงเพื่อสร้างคำสั่งใหม่
$myvar = 'somevalue'; $x = $_GET['arg']; eval('$myvar = ' . $x . ';');
คำสั่งเช่นนี้เปิดโอกาสให้ผู้ที่ใส่อินพุตเพื่อมุ่งร้ายต่อระบบสามารถเพิ่มคำสั่งอื่นๆ เช่น การใส่อินพุตเป็น 10; system('/bin/echo uh-oh')
ทำให้อินพุตเช่นนี้สามารถรันคำสั่งใดๆ ก็ได้ตามที่ผู้ใช้ที่มุ่งร้ายต้องการในสิทธิเท่ากับที่เว็บเซิร์ฟเวอร์สามารถทำได้
กระบวนการนี้เจาะผ่านช่องโหว่ที่ซอฟต์แวร์กลั่นกรองอินพุตจากผู้ใช้ไม่ดีพอเช่นนี้เป็นปัญหาที่พบบ่อย โดยเฉพาะการใช้งานกับระบบฐานข้อมูล SQL ที่สคริปต์เว็บต่างๆ ต้องสร้างคำสั่ง SQL ไปยังฐานข้อมูล เราเรียกช่องโหว่เช่นนี้ว่า SQL Injection ตัวอย่างเช่นการสร้าง SQL จากอินพุต
$statement = "SELECT * FROM users WHERE name = '" + userName + "';";
ในคำสั่งเช่นนี้ไม่มีการตรวจสอบตัวแปร userName ที่เป็นอิตพุตก่อนใช้งาน อินพุตที่มุ่งร้ายอาจจะเป็น ' or '1'='1
ทำให้คำสั่ง SQL สุดท้ายกลายเป็นเป็น การเรียกรายชื่อผู้ใช้ทั้งหมดจากฐานข้อมูล
SELECT * FROM users WHERE name = '' OR '1'='1';
คำสั่งที่มุ่งร้ายในการดึงข้อมูลออกมาจากฐานข้อมูลเป็นแหล่งสำคัญที่เว็บต่างๆ ถูกเจาะฐานข้อมูลออกมา ผู้ร้ายบางส่วนอาจจะใช้ช่องโหว่แบบเดียวกันลบฐานข้อมูลออกไปทั้งหมด สร้างความเสียหายให้กับระบบมากยิ่งขึ้น
ระบบจัดการเนื้อหา และเว็บเฟรมเวิร์ครุ่นใหม่ๆ ทั้งหมดล้วนมีกระบวนการกรองอินพุตผู้ใช้ สำหรับคำสั่ง SQL นั้นการพัฒนาเว็บในช่วงหลังจะไม่แนะนำให้สร้างคำสั่ง SQL โดยตรงอีกต่อไป แต่แนะนำให้ครอบคำสั่งด้วยด้วยชั้นซอฟต์แวร์ เช่น ORM (object-relational mapping) ทำให้ผู้ใช้ที่มุ่งร้ายไม่สามารถสร้างโค้ดคำสั่งนอกเหนือจากรูปแบบที่เราต้องการได้อีกต่อไป
สำหรับ PHP ที่นิยมใช้ทำเว็บนั้น ในรุ่นหลังๆ มีการเพิ่มชั้น PHP Data Objects (PDO) ที่กระบวนการทำงานง่ายกว่า ORM แต่มีกระบวนการกรองอินพุตเช่น
$db = new PDO('mysql:host=localhost;dbname=', ' ', 'PASSWORD'); $stmt = $db->prepare("select contenttype, imagedata from images where id=?"); $stmt->execute(array($_GET['id']));
กระบวนการนี้ทำให้ผู้ใช้ที่มุ่งร้ายไม่สามารถสร้างอินพุตที่ทำงานนอกเหนือจากที่โค้ดกำหนดไว้ได้
กระบวนการเจาะเว็บในยุคหลังมีซอฟต์แวร์สามารถสแกนเว็บเพื่อค้นหาช่องโหว่ต่างๆ ได้อย่างมีประสิทธิภาพ การสร้างเว็บในยุคหลังจึงควรทำตามคำแนะนำของเฟรมเวิร์คต่างๆ อย่างระมัดระวัง แต่กระนั้นแม้แต่ระบบจัดการเนื้อหาชื่อดังจำนวนมากก็มีช่องโหว่ค้นพบใหม่อยู่เป็นระยะ การอัพเดตซอฟต์แวร์ให้ทันสมัยเสมอจึงเป็นเรื่องจำเป็น แม้จะเป็นการใช้เฟรมเวิร์คก็ตาม
ตัวอย่างจากในบทความนี้นำมาจาก Wikipedia: Code Injection, Wikipedia: SQL Injection, และ PHP Manual: PDO
Comments
ตามคอมมิวนิตี้ของพวก hacker ด้วยจะได้รู้เท่าทัน :)
บทความชุดความปลอดภัยคอมพิวเตอร์อันนี้เป็นตอนที่ 4 ส่วน 3 ตอนแรกได้แก่
คำเตือนในบทความก่อนหน้านี้ยังคงมีผลต่อบทความทุกบทความในชุดนี้และทุกข่าวที่เกี่ยวข้องกับความปลอดภัย
คำเตือน: บทความในชุดการรักษาความปลอดภัยคอมพิวเตอร์ มีจุดประสงค์หลักเพื่อการศึกษา และการระมัดระวังของนักพัฒนา การทดสอบต้องทำในสภาพแวดล้อมปิดเท่านั้น (ตั้งเซิร์ฟเวอร์เฉพาะเอง ทดสอบเสร็จแล้วปิดบริการ) ห้ามทดสอบในเว็บจริงที่ให้บริการอยู่ หากผมทราบว่าสมาชิก Blognone มีการทดลอง โทษคือแบนถาวรอย่างเดียวไม่ว่าจะเกิดความเสียหายหรือไม่
lewcpe.com, @wasonliw
อยากให้มี section เรื่องความปลอดภัยบนเว็บครับ
ขอบคุณสำหรับบทความครับ แต่เห็นโดนกันได้โดนกันดี โดยเฉพาะมหากาพย์ Sony
ตรงนี้ไม่น่ามี , นะครับ
สแกน
สแกน
เยี่ยมครับ
จะว่าไปผมเองก็หันมาใช้ CodeIgniter มาได้สักพักล่ะ ช่วยเรื่องการกรองข้อมูลได้เยอะเลย
บล็อกส่วนตัวที่อัพเดตตามอารมณ์และความขยัน :P
ข่าวนี้โดนบักหรือเปล่าครับ ทำไมมันกลายเป็นแบบนี้ http://www.blognone.com/node/42857 ทั้งๆ ที่ตอนแรกมันไม่เป็นแบบนี้
แจ้งปัญหาอื่นๆ ให้แจ้งในฟอรั่มหรือในตัวข่าวครับ
lewcpe.com, @wasonliw
ผมว่าตอนนี้ที่น่ากลัวกว่าคือการแสการเซ็ต FastCGI บน nginx/lighttpd โดย proxy ไป php-fpm หรือ Apache เพราะมันจะมีการหลอก PATHINFO เต็มไปหมดเลย
เป็นเทคนิคการเจาะที่ผ่านมาหลายปี แต่ก็ยังโดนกันทุกวัน
ไม่เคยลองกับตัวเองเลย (เดี๋ยวต้องลองทดสอบกับเจ้า Raspberry Pi ที่บ้านดู หลังๆไม่ค่อยได้หัดเขียนเว็บซักเท่าไหร่)
"เผลอเรอ" >> "เผอเรอ"
ภาษาไทย เผลอ ถูกแล้วนะครับ
ถ้าจะเขียนเผอเรอ ต้องเขียนอย่างที่ถูกท้วงข้างบน
ขอบคุณสำหรับความรู้ครับ ผมเข้าใจผิดมาตลอดเลยว่าคำนี้เขียนว่า "เผลอเรอ"
คิดเอาเองว่า "เผลอ" น่าจะมาจากคำว่า "เผอเรอ" ครับ
แต่ถ้าเผลอเรอ คงเป็นอาการหลังการรับประทานอาหาร
^
^
that's just my two cents.
กลิ่นมาเลยครับ -__-
โค้กเย็นๆสักขวดกระดกรวดเดียวหมด มาทันทีครับ
เมื่อก่อน se-ed.net เปิดให้ใช้php hostingฟรี
แต่เปิดคำสั่งsystemทิ้งไว้ เลยโดยคำสั่ง commandไปอีกที ทั้ง dir แต่ละdrive เปิด office เปิด winampและ notepad
ใช้ xampp adodb php mysql ไม่กล้าเปลี่ยนเทคนิคซะที
เพิ่ม adapt class autoload ของ php 5.3 มาใช้
pdo คงอีกซักพัก แต่คิดว่าคงยากเพราะเปลี่ยนแนวการเขียน และ debug หมดเลย
ขอบคุณมาก ๆ ครับสำหรับความรู้ดี ๆ
น่ากลัวจุงเบย สมัยตอนผมเป็นมือปืนรับจ้างแฮก ผมว่ารายได้ดีนะ หลักแสนถึงหลายล้าน
เรื่อง SQL injection นี่เห็นทีไรก็นึกถึง xkcd ตอนนี้ ทุกที
pittaya.com
เว็บนี้มุกลึกเกินครับ ผมอ่านแล้วไม่เคยเข้าใจเลย รบกวนอธิบายหน่อยครับ
_/ _ ขอบคุณครับ
ตั้งชื่อลูกเป็นคำสั่ง SQL ที่มีคำสั่งลบ(drop) table หน่ะครับ
Russia is just nazi who accuse the others for being nazi.
someone once said : ผมก็ด่าของผมอยู่นะ :)
SQL Injection กันท่านี้เลยทีเดียว O_o
อ่อ ... ขอบคุณครับ งงมานานกับเว็บนี้
ตั้งแต่เขียน MVC มานี้ก็ไม่ได้จับ SQL command เลยครับ ทำให้สบายใจเรื่องนี้ไปได้นิดหน่อยครับ :)