แค่ hash ก็ทำให้เว็บปลอดภัยขึ้น

เวลาเขียนระบบอะไรขึ้นมาก็ตาม สิ่งที่ต้องระวังก็คือความซุกซนของผู้ใช้งาน
แน่นอนว่าระบบส่วนใหญ่จะมีการแบ่งสิทธิ์การใช้งาน เมนูเดียวกันแต่ผู้ใช้งานคนละคนก็จะเห็นข้อมูลไม่เท่ากัน
วันนี้ผมจะมาแนะนำวิธีป้องกันการเข้าถึงข้อมูลโดยไม่ได้รับอณุญาติที่ง่ายสุดๆมาฝากครับ

นั่นคือการใช้ hash เข้าช่วย
ซึ่ง function hash ก็มีมากมายหลายตัวให้ใช้งานกันไม่ว่าจะเป็น CRC32 MD5 SHA1
เวลาส่งข้อมูลในระบบ ผมจะสมมติระบบ Personal Message (PM) ขึ้นมาละกันครับ
ในระบบจะมีหน้าอ่าน PM อยู่ ผมให้ชื่อว่า viewPM.php ซึ่งจะรับ get parameter ที่ชื่อ id มาเป็นเลขที่ข้อความ

คนทั่วไปก็จะใช้วิธี ตรวจสอบว่าผู้ใช้งานมีสิทธิ์อ่านข้อความรึเปล่า

$result = mysql_query("SELECT * FROM `pm_message` WHERE `pm_id` = '{$_GET['id']}'");
$row = mysql_fetch_assoc($result);
if($row['destination'] != $myUserID)
{
      //Error ไม่มีสิทธิ์อ่าน
}

ประเด็นคือ
1. คุณต้องตรวจสอบว่ามีข้อความดังกล่าวอยู่ในระบบจริงๆรึเปล่า (แทรกก่อนจะ fetch data)
2. คุณต้องตรวจสอบว่าผู้ใช้งานมีสิทธิ์อ่านรึเปล่า ซึ่งในตัวอย่างเป็นแบบง่ายๆ นั่นก็คือขอแค่ user ตรงพอ
แต่บางระบบมันจะซับซ้อนกว่ามากเช่น ผู้อ่านหลายคนหรือ Admin สามารถดูได้หมด
3. แน่นอนว่าคุณต้อง query ข้อมูลเพื่อทำ 1. และ 2.

แต่ถ้าหันมาใช้ hash เข้าช่วยแล้วจะแก้ปัญหา 1 – 3 ได้หมดเลยนั่นคือ

if($_GET['hash'] == md5('SALT'.$_GET['id'].'MORE SALT like UserID, SessionID, or IP address up to you'))
{
   $result = mysql_query("SELECT * FROM `pm_message` WHERE `pm_id` = '{$_GET['id']}'");
   $row = mysql_fetch_assoc($result);
//Show data
}
else
{
  //Error -> Data has been modified
}

เวลาผู้ใช้งานได้ลิงค์มา ก็จะเป็น viewPM.php?id=6&hash=XXXXXXXXXXXXXXXX(ยาวเท่าไหร่ก็ขึ้นอยู่กับว่าจะเลือกใช้งานตัวไหน)
ข้อดีคือไม่เป็นภาระ SQL Server เลย เพราะว่าจะมีการตรวจสอบเบื้องต้นก่อนแล้วว่าข้อมูลที่ได้มาจะเป็นข้อมูลที่ถูกต้องแน่นอน
กรณีที่ผู้ใช้งานแก้ตัวเลขเล่นก็จะไม่ต้องไป query ข้อมูลให้เปลือง
แต่ข้อเสียก็คือระบบต้องมาประมวลผล hash แทน ซึ่งผมว่าถ้าใช้พวก CRC32 จะไวมากๆ (แต่ในตัวอย่างไม่แสดงเพราะว่า ต้องปรับข้อมูลให้มันสวยงามโดยพวก sprintf ซึ่งคิดว่าไปลองเล่นกันเองดีกว่า)

การจะเจาะระบบเข้ามาได้มีอยู่สองกรณีคือ
1. เดา hash ถุก ซึ่งถ้าเป็น MD5 จะมีความน่าจะเป็นคือ 1 ใน 2 ยกกำลัง 128
(มาจาก MD5 จะได้ binary data มา 16byte แต่ละ byte ก็มีความน่าจะเป็น 255 ค่าซึ่งคือ 2 ยกกำลัง 8; ดังนั้นมี 16 byte ก็เอา 2^8 มาคูณกัน 16 ครั้ง)
2. รู้ว่าการคิด hash มาได้อย่างไร พูดง่ายๆก็คือเดา salt ถูกนั่นเอง ซึ่งผมว่ายากกว่ามากๆ เพราะว่าเราอาจจะเอา parameter แทรกตรงกลาง
เอาไว้ข้างหน้า เอาไว้ข้างหลัง หรือเอาไว้หลายๆที่ ก็เป็นไปได้ทั้งสิ้น

Facebooktwittermailby feather
ข้อความนี้ถูกเขียนใน PHP, Programming คั่นหน้า ลิงก์ถาวร

ใส่ความเห็น