บางครั้งการที่เราไปเช่าเว็บโฮสต์ติ้ง เพื่อฝากเว็บไซต์ไว้นั้น มันอาจจะไม่ปลอดภัย ถ้าโฮสต์ติ้งดูแลด้านการรักษาความปลอดภัยเซิร์ฟเวอร์ไม่ดีพอ หลายคนเคยโดนแฮกเพราะการเขียนเว็บเพจที่มีช่องโหว่ หรือ ใช้โปรแกรมสำเร็จที่มีช่องโหว่ เนื่องจากไม่ได้อัพเกรดเวอร์ชั่น แต่จะมีกรณีนอกเหนือคือ โดนแฮกที่เซิร์ฟเวอร์เลย มีผลทำให้เว็บไซต์ทุกเว็บที่ฝากไว้ในเซิร์ฟเวอร์นั้น โดนกันทั่วหน้า
เกิดขึ้นมาแล้ว... กรณีที่เกิดนี้เกิดจากปัญหาการตั้งคอนฟิกของ php นั่นเอง ทางเซิร์ฟเวอร์มีการเซตค่า registry global เป็น on แล้วเหล่าแฮกเกอร์ก็เจาะผ่านเข้ามาที่เครื่องได้
มาอธิบายเกี่ยวกับ registry global กันหน่อย ... ไปคัดมาจากที่มีคนอธิบาย ซึ่งค่อนข้างจะเป็นเทคนิคหน่อย ใครที่ไม่ไหวก็ข้ามไปอ่านบรรทัดสุดท้ายเลยนะ
ใน PHP มีตัวตั้งค่าตัวหนึ่ง ชื่อ register_globals
(ตั้งแต่ PHP > 4.2.3 ตั้งค่าได้ใน php.ini หรือ .htaccess
หรือ httpd.conf หรือ ... คือเป็น PHP_INI_PERDIR)
ถ้าตัวนี้เป็น on แล้ว ตัวแปรหลาย ๆ ตัวก็จะกลายเป็นตัวแปรที่เป็น global
เช่น ตัวแปรที่รับจาก http GET หรือ POST ก็จะรับได้ตรง ๆ
เช่น http://foobar.com?foo=bar
เมื่อ php ทำงานก็จะสร้าง $foo ซึ่งมีค่า bar มาให้
คำถามต่อไปมีว่า (register_globals = on) ดีหรือไม่ - -?
คำตอบแบบกระชับ คือ มองในแง่ความง่ายแล้วดี (Rasmus L. เคยให้ความเห็นทำนองนี้)
แต่อาจจะมีปัญหาเรื่อง ความปลอดภัย ในกรณีที่เขียนโปรแกรมแบบหลวม ๆ
ตัวอย่างแคละสิก ของเรื่องนี้ เช่น
// index.php
if ('admin' == $user && 'enigma' == $password) {
$foo = 'foolaccess';
}
if ('foolaccess' == $foo) {
// Go to secret page.
}
// Go to normal page.
แล้ววันดีคืนดีก็มีคนมาเรียก page นี้ โดยเรียก index.php?foo=foolaccess
ผลก็คือ สามารถเข้าไปหน้า secret page ได้ (นั่นหมายความถึง เข้าไปได้โดยไม่ปกติ หรือ โดนแฮก นั่นเอง)
คำถามต่อไปมีว่า ....แล้วจะใช้อะไรแทนดี - -?
คำตอบคือ superglobals เช่น $_GET, $_POST ซึ่งมีให้ใช้ตั้งแต่ PHP4.1.0
มีปัญหาหรือไม่ - -?
ถ้ายังส่งต่อไปให้แบบเดิม ก็ ปัญหาเดิม เช่น
$user = $_GET['user']; // หรือ = $_POST['user']; ก็ตาม
ปัญหาก็ยังเหมือนเดิม คือ ใคร ๆ ก็สามารถเปลี่ยนค่า user ได้
นั่นเพราะปัญหาจากตัวอย่าง แท้จริงมิได้เป็นปัญหาจาก global
แต่เป็นปัญหาการเขียนโปรแกรมที่ ตัวแปรไม่ถูกกำหนดค่าเริ่มต้น (uninitialized)
รู้เช่นนั้นแล้วทำไมยังต้องใช้ superglobals อีก
- มีปัญหาเรื่องอื่นอีก
- บั๊กที่เกิดในกรณี register_globals = on มี priority ต่ำในการแก้
(เหตุเพราะ default ของ register_globals เป็น off ตั้งแต่ PHP4.2.0
จากการถูก vote ให้ off เพราะคิดว่าทำให้เกิดความปลอดภัย
มากขึ้นต่อผู้เริ่ม ใช้/เขียน PHP)
- register_globals จะถูกถอดทิ้งใน PHP6 (ไม่มีให้ตั้งค่าแล้ว)
( มีโหวตให้เอาออกตั้งแต่ PHP5.3 ด้วย แต่ ผลโหวตยังให้มีอยู่ )
เพิ่มเติม
จริง ๆ แล้ว PHP มีเครื่องมือช่วยสำหรับ uninitilized vairable
ก็คือ ถ้า ตั้งค่าเป็น E_ALL (คือให้แสดง notice ด้วย)
ถ้ามี uninitilized variable แล้ว PHP ก็จะแสดง notice ( /me ทำใน Development)
คำถามว่า อยู่ที่ไหน ไฟล์อะไรนั้น ก็ php.ini
สิ่งที่ลูกค้าจะทำได้ คือ นั่งรอ เค้าแก้ไข ลงโปรแกรมบนเซิร์ฟเวอร์ใหม่ เท่านั้นเอง