Security
น้องๆ หลายคนคงเคยได้ยินคำว่า OWASP Top 10 กันมาบ้างแล้วใช่มั้ย? มันคือรายการจัดอันดับช่องโหว่ (vulnerability) ที่พบบ่อยที่สุดในเว็บแอปพลิเคชัน ที่ทาง OWASP (Open Web Application Security Project) เขาทำขึ้นมา update ทุกๆ 2-3 ปี เพื่อให้นักพัฒนาอย่างเราๆ ได้รู้ว่าอะไรคือภัยคุกคามอันดับต้นๆ ที่ต้องระวังเป็นพิเศษ
สมัยผมทำร้านเน็ต SiamCafe.net เมื่อ 20 กว่าปีที่แล้ว เรื่อง security นี่ถือว่าใหม่มากๆ เลยนะ ตอนนั้นยังไม่มีใครพูดถึง OWASP Top 10 แบบจริงจัง แต่พอเว็บเริ่มซับซ้อนขึ้น โดน hack กันบ่อยๆ เราก็เริ่มตระหนักถึงความสำคัญของมัน และเอามาปรับใช้ในการพัฒนาเว็บของร้านเราเอง
วันนี้พี่บอมจะมาสรุป OWASP Top 10 ฉบับเข้าใจง่าย สไตล์ SiamCafe ให้ฟังกันครับ รับรองว่าอ่านจบแล้ว เอาไปใช้ป้องกันเว็บของน้องๆ ได้แน่นอน
Broken Access Control คืออะไร? มันคือช่องโหว่ที่ทำให้ผู้ใช้งานสามารถเข้าถึงข้อมูล หรือฟังก์ชันที่ไม่ได้รับอนุญาตให้เข้าถึงได้ พูดง่ายๆ คือ "สิทธิ์" ที่เราตั้งไว้มัน "พัง" นั่นเอง
ลองนึกภาพว่า น้องๆ ทำเว็บอีคอมเมิร์ซ แล้วลูกค้าคนนึงสามารถเข้าไปดูข้อมูลส่วนตัวของลูกค้าคนอื่นได้, แก้ไขราคาสินค้าได้, หรือแม้กระทั่งลบสินค้าออกจากระบบได้ แบบนี้เจ๊งแน่นอน!
สมัยก่อนตอนทำ SiamCafe Blog SiamCafe Blog ก็เคยเจอเคสที่ user ทั่วไปสามารถเข้าไปแก้ไขบทความของ admin ได้ เพราะ permission มันตั้งค่าผิดพลาด โชคดีที่รู้ตัวเร็ว แก้ไขทันก่อนจะเสียหายหนัก
// ตัวอย่าง PHP code (แบบไม่ปลอดภัย)
$user_id = $_GET['user_id']; // รับ user_id จาก URL
// ดึงข้อมูลผู้ใช้จากฐานข้อมูล (โดยไม่มีการตรวจสอบสิทธิ์)
$sql = "SELECT * FROM users WHERE id = $user_id";
$result = mysqli_query($conn, $sql);
$user = mysqli_fetch_assoc($result);
// แสดงข้อมูลผู้ใช้
echo "Username: " . $user['username'];
echo "Email: " . $user['email'];
// ตัวอย่าง PHP code (แบบปลอดภัย)
$user_id = $_GET['user_id'];
// ตรวจสอบว่าผู้ใช้มีสิทธิ์เข้าถึงข้อมูลหรือไม่
if (is_admin() || $user_id == $_SESSION['user_id']) {
$sql = "SELECT * FROM users WHERE id = $user_id";
$result = mysqli_query($conn, $sql);
$user = mysqli_fetch_assoc($result);
echo "Username: " . $user['username'];
echo "Email: " . $user['email'];
} else {
echo "You are not authorized to view this user's information.";
}
function is_admin() {
// ตรวจสอบว่า user เป็น admin หรือไม่ (อาจจะ query จาก database หรือ check จาก session)
// ...
return false; // default: not admin
}
Cryptographic Failures คืออะไร? มันคือปัญหาที่เกิดจากการใช้ cryptography (การเข้ารหัส) อย่างไม่ถูกต้อง หรือไม่เพียงพอ ทำให้ข้อมูลสำคัญรั่วไหลได้
ถ้าเราเก็บรหัสผ่านของลูกค้าแบบ plain text (ไม่ได้เข้ารหัส) แล้วโดน hack ข้อมูลไป ลูกค้าคงไม่กลับมาใช้บริการเราอีกแน่นอน นอกจากนี้ ข้อมูลสำคัญอื่นๆ เช่น ข้อมูลบัตรเครดิต, ข้อมูลส่วนตัว, ข้อมูลทางการแพทย์ ก็ต้องเข้ารหัสอย่างถูกต้องด้วย
สมัยก่อนตอนทำร้านเน็ต SiamCafe, เรื่องการเข้ารหัสข้อมูลสำคัญยังไม่ค่อยเป็นที่แพร่หลายเท่าไหร่ แต่พอมีข่าวการ hack ข้อมูลออกมาเรื่อยๆ เราก็เริ่มให้ความสำคัญกับเรื่องนี้มากขึ้น
// ตัวอย่าง PHP code (แบบไม่ปลอดภัย)
$password = $_POST['password']; // รับ password จาก form
// เก็บ password แบบ plain text
$sql = "INSERT INTO users (username, password) VALUES ('john', '$password')";
mysqli_query($conn, $sql);
// ตัวอย่าง PHP code (แบบปลอดภัย)
$password = $_POST['password'];
// สร้าง salt
$salt = bin2hex(random_bytes(16));
// Hash password ด้วย bcrypt
$hashed_password = password_hash($password . $salt, PASSWORD_BCRYPT);
// เก็บ salt และ hashed password ในฐานข้อมูล
$sql = "INSERT INTO users (username, password, salt) VALUES ('john', '$hashed_password', '$salt')";
mysqli_query($conn, $sql);
// ฟังก์ชันตรวจสอบ password
function verifyPassword($password, $hashed_password, $salt) {
return password_verify($password . $salt, $hashed_password);
}
Injection คืออะไร? มันคือช่องโหว่ที่เกิดจากการแทรก code ที่เป็นอันตรายเข้าไปใน query หรือ command ที่ส่งไปยังระบบ เช่น SQL injection, Command injection, LDAP injection
ถ้าเราไม่ validate input ที่รับมาจากผู้ใช้ให้ดี Hacker สามารถแทรก SQL code เข้าไปใน input field แล้วสั่งให้ database ทำอะไรก็ได้ เช่น ดึงข้อมูลทั้งหมด, ลบข้อมูล, หรือแม้กระทั่ง inject malware เข้าไปในระบบ
สมัยก่อน ตอนทำ SiamCafe Blog SiamCafe Blog เคยโดน SQL injection เล่นงานเหมือนกัน ตอนนั้นยังไม่มีความรู้เรื่อง prepared statement ก็เลยโดน hacker เข้ามาแก้ไขข้อมูลใน database โชคดีที่ backup ไว้ เลยกู้คืนได้ทัน
// ตัวอย่าง PHP code (แบบไม่ปลอดภัย)
$username = $_GET['username']; // รับ username จาก URL
// สร้าง SQL query (โดยไม่มีการ escaping)
$sql = "SELECT * FROM users WHERE username = '$username'";
$result = mysqli_query($conn, $sql);
// ตัวอย่าง PHP code (แบบปลอดภัย)
$username = $_GET['username'];
// ใช้ prepared statement
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ?");
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->get_result();
// หรือใช้ escaping function
$username = mysqli_real_escape_string($conn, $_GET['username']);
$sql = "SELECT * FROM users WHERE username = '$username'";
$result = mysqli_query($conn, $sql);
ดูวิดีโอเพิ่มเติมเกี่ยวกับOWASP Top 10 สรุปภาษาไทย:
| อันดับ | ชื่อช่องโหว่ | คำอธิบาย | วิธีป้องกันหลัก |
|---|---|---|---|
| A01 | Broken Access Control | การควบคุมการเข้าถึงที่ไม่ถูกต้อง | Least privilege, RBAC, Validation |
| A02 | Cryptographic Failures | การเข้ารหัสที่ไม่ถูกต้อง | Strong algorithms, Secure key management, TLS |
| A03 | Injection | การแทรก code ที่เป็นอันตราย | Prepared statements, Input validation, Escaping |
| A04 | Insecure Design | การออกแบบระบบที่ไม่ปลอดภัย | Secure SDLC, Threat modeling, Security patterns |
| A05 | Security Misconfiguration | การตั้งค่าระบบที่ไม่ปลอดภัย | Hardening, Automation, Configuration management |
| A06 | Vulnerable and Outdated Components | การใช้ components ที่มีช่องโหว่และล้าสมัย | Software composition analysis, Patching, Monitoring |
| A07 | Identification and Authentication Failures | การระบุตัวตนและการยืนยันตัวตนที่ไม่ถูกต้อง | Multi-factor authentication, Strong password policies |
| A08 | Software and Data Integrity Failures | ความล้มเหลวในการรักษาความสมบูรณ์ของซอฟต์แวร์และข้อมูล | Code signing, Integrity checks, Data validation |
| A09 | Security Logging and Monitoring Failures | ความล้มเหลวในการบันทึกและตรวจสอบความปลอดภัย | Centralized logging, Alerting, Incident response |
| A10 | Server-Side Request Forgery (SSRF) | การปลอมแปลงคำขอจากฝั่ง server | Input validation, Whitelisting, Network segmentation |
OWASP Top 10 ช่วยให้นักพัฒนาเข้าใจถึงภัยคุกคามที่พบบ่อยที่สุด และสามารถนำไปใช้ในการปรับปรุงความปลอดภัยของเว็บแอปพลิเคชันได้
OWASP จะ update Top 10 ทุกๆ 2-3 ปี เพื่อให้สอดคล้องกับภัยคุกคามที่เปลี่ยนแปลงไป
เริ่มต้นด้วยการอ่าน OWASP Top 10 ฉบับล่าสุด, ทำความเข้าใจแต่ละช่องโหว่, และลองทำ lab เพื่อทดสอบการป้องกันช่องโหว่ต่างๆ
สมัยผมทำร้านเน็ต ผมจะสอนเด็กๆ ที่ร้านเสมอว่า "อย่าเชื่อใจ Input จาก User เด็ดขาด!" วิธีป้องกัน SQL Injection ที่ง่ายที่สุดคือการใช้ Parameterized Queries หรือ Prepared Statements มันจะช่วยแยก Data กับ Command ออกจากกัน ทำให้ Hacker ไม่สามารถ Inject คำสั่ง SQL เข้ามาได้
-- ตัวอย่าง PHP (PDO)
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->execute([$username, $password]);
$user = $stmt->fetch();
ถ้าเลี่ยงไม่ได้จริงๆ ต้องใช้ String concatenation ก็ให้ใช้ Function ที่ Escape Special Characters ก่อนเสมอ เช่น `mysqli_real_escape_string()` ใน PHP หรือ `sanitize()` ใน Framework อื่นๆ
XSS นี่ตัวดีเลย สมัยก่อนเจอเยอะมาก พวก Comment Board ที่ใส่ Script อะไรแปลกๆ ได้ วิธีป้องกันคือ Escape Output เสมอ! ก่อนจะแสดงผลอะไรที่มาจาก User Input ต้อง Convert พวก Special Characters ให้เป็น HTML Entities ก่อน
<!-- ตัวอย่าง HTML Entities -->
<script>alert("XSS")</script> --> <script>alert("XSS")</script>
ถ้าใช้ Framework สมัยใหม่ พวกนี้จะมี Auto-Escaping ให้แล้ว แต่ก็ต้องเช็คให้ดีนะ อย่าประมาท!
เรื่อง Authentication กับ Authorization นี่อย่าพยายามเขียนเองเลยครับ ใช้ Library หรือ Framework ที่มัน Built-in มาให้ดีกว่าเยอะ เพราะมันมี Security Flaws ที่เราคาดไม่ถึงเยอะมาก เช่นเรื่อง Session Management, Password Hashing, Role-Based Access Control พวกนี้ละเอียดอ่อนมาก
สมัยก่อนผมเคยเขียนระบบ Login เอง แล้วโดน Hack เพราะลืมเรื่อง Session Hijacking ไปเลย เข็ดจนตาย!
OWASP Top 10 คือ List ของช่องโหว่ Web Application ที่พบบ่อยที่สุด และมีความเสี่ยงสูงที่สุด ถ้าเราเข้าใจ และป้องกันช่องโหว่เหล่านี้ได้ ก็จะช่วยลดความเสี่ยงในการโดน Hack ได้เยอะมาก
คิดซะว่ามันคือ Checklist พื้นฐาน ที่ Developer ทุกคนต้องรู้ครับ
ถ้าไม่ได้ใช้ Framework ก็ต้อง Code เองทุกอย่าง ซึ่งมันก็ยากกว่าเยอะ แต่หลักการก็เหมือนกันคือ:
สำคัญคือต้องเข้าใจหลักการทำงานของแต่ละช่องโหว่ แล้วเขียน Code ป้องกันให้ครอบคลุม
มี Tool เยอะแยะเลยครับ ทั้ง Open Source และ Commercial เช่น OWASP ZAP, Burp Suite, Acunetix พวกนี้จะช่วย Scan หาช่องโหว่ต่างๆ ใน Web Application ของเราได้ แต่ Tool พวกนี้ก็ไม่ใช่ยาวิเศษ มันแค่ช่วย Detect ช่องโหว่เบื้องต้น สุดท้ายแล้วก็ต้องใช้ Human Review ด้วยเสมอ
และอย่าลืม SiamCafe Blog มีบทความดีๆ อีกเยอะ
มี Resources เยอะมากครับ ทั้ง Online Courses, Books, Conferences OWASP เองก็มี Resources ฟรีๆ ให้ศึกษาเยอะแยะ นอกจากนี้ก็มี Community ต่างๆ ที่คอยช่วยเหลือกัน ที่สำคัญคือต้องหมั่น Update ความรู้ และติดตามข่าวสารเรื่อง Security อยู่เสมอ
iCafeForex ก็เป็นแหล่งความรู้ที่ดี
OWASP Top 10 คือ Checklist พื้นฐานที่ Developer ทุกคนต้องรู้ การป้องกันช่องโหว่เหล่านี้ไม่ใช่เรื่องยาก แต่ต้องอาศัยความเข้าใจ และความใส่ใจ อย่าประมาท! เพราะช่องโหว่เล็กๆ อาจนำไปสู่ความเสียหายใหญ่หลวงได้
สมัยผมทำร้านเน็ต ผมจะย้ำกับเด็กๆ เสมอว่า "Security ไม่ใช่ Option แต่มันคือ Requirement!"