การเรียนรู้ OWASP A01 และ A02: Broken Access Control และ Security Misconfiguration

8 นาที 12 views บันทึกเป็น PDF
การเรียนรู้ OWASP A01 และ A02: Broken Access Control และ Security Misconfiguration

ทำไมโปรแกรมเมอร์ต้องรู้จัก OWASP Top 10...

ทำไมโปรแกรมเมอร์ต้องรู้จัก OWASP Top 10

เวลาเราเขียนเว็บแอปพลิเคชันขึ้นมาสักตัว เรามักจะโฟกัสไปที่ฟีเจอร์ให้มันทำงานได้ตามใจลูกค้า แต่บางครั้งเราลืมไปว่าโลกออนไลน์มีคนที่จ้องจะเจาะระบบเราอยู่ตลอดเวลา OWASP Top 10 คือรายชื่อช่องโหว่ (จุดอ่อนของโปรแกรมที่แฮกเกอร์ใช้โจมตีได้) ที่อันตรายและพบบ่อยที่สุดในโลก ซึ่งเปรียบเสมือนคู่มือความปลอดภัยที่โปรแกรมเมอร์มืออาชีพทุกคนต้องอ่าน

การเข้าใจเรื่องนี้ไม่ใช่แค่เรื่องของสายงานความปลอดภัย (Security) เท่านั้น แต่มันคือทักษะพื้นฐานในการเขียนโค้ดให้มีคุณภาพ หากเราเขียนโปรแกรมโดยไม่คำนึงถึงความปลอดภัย วันหนึ่งเมื่อแอปของเรามีคนใช้งานจริง ข้อมูลสำคัญของลูกค้าอาจจะรั่วไหลออกไปได้โดยที่เราไม่รู้ตัว ซึ่งนั่นคือฝันร้ายของนักพัฒนาทุกคน

ในบทความนี้เราจะมาเจาะลึก 2 เรื่องแรกคือ A01: Broken Access Control (การควบคุมการเข้าถึงที่ผิดพลาด) และ A02: Security Misconfiguration (การตั้งค่าความปลอดภัยที่ไม่ถูกต้อง) ซึ่งเป็นด่านแรกที่แฮกเกอร์มักจะลองทดสอบกับเว็บไซต์ของเราเสมอ ถ้าเราป้องกันสองจุดนี้ได้แน่นหนา ก็ถือว่าเราปิดประตูไปได้หลายบานแล้ว

A01: Broken Access Control คืออะไร

ลองนึกภาพว่าคุณสร้างระบบสมาชิกขึ้นมา แล้วมีคนพิมพ์ URL (ที่อยู่ของเว็บไซต์) ตรงไปที่หน้าแอดมิน เพื่อเข้าไปลบข้อมูลคนอื่นได้ ทั้งที่เขาไม่ได้เป็นแอดมิน นั่นแหละครับคือสิ่งที่เรียกว่า Broken Access Control มันคือการที่ระบบของเราไม่ได้ตรวจสอบสิทธิ์ของคนใช้งานให้ดีพอว่าคนนี้ "มีสิทธิ์ทำสิ่งนั้นจริงๆ หรือไม่"

ปัญหาที่พบบ่อยที่สุดคือ IDOR (Insecure Direct Object Reference) หรือการที่ระบบยอมให้คนเปลี่ยนเลขไอดีใน URL เพื่อดูข้อมูลของคนอื่น เช่น ถ้าหน้าโปรไฟล์ของคุณคือ /user/123 แล้วคุณลองแก้เป็น /user/124 แล้วดันเห็นโปรไฟล์คนอื่นขึ้นมา นั่นแปลว่าระบบของคุณมีช่องโหว่ร้ายแรงที่ไม่ได้เช็กว่าไอดีที่ขอมา เป็นเจ้าของข้อมูลจริงๆ หรือเปล่า

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

ตัวอย่างโค้ดที่เสี่ยงต่อการถูกเจาะระบบ

มาดูตัวอย่างการเขียนโค้ดที่ผิดพลาด ซึ่งเปิดโอกาสให้คนแอบดูข้อมูลคนอื่นได้ง่ายๆ โดยการเปลี่ยนค่าใน URL

// โค้ดที่ผิด: ดึงข้อมูลตาม ID ที่รับมาจาก URL ตรงๆ
app.get('/user/profile', (req, res) => {
  const userId = req.query.id; // รับไอดีมาจาก URL
  const userData = db.getUserById(userId); // ดึงข้อมูลจากฐานข้อมูลทันที
  res.send(userData);
});

อธิบายโค้ด:

  • req.query.id คือการดึงค่าไอดีที่ผู้ใช้ใส่มาในลิงก์ เช่น ?id=123
  • db.getUserById(userId) คือการสั่งให้ฐานข้อมูลไปเอาข้อมูลของไอดีนั้นมาแสดง
  • บรรทัดนี้อันตรายเพราะไม่มีการตรวจสอบว่า userId ที่ใส่มานั้น เป็นเจ้าของบัญชีที่ล็อกอินอยู่จริงไหม

ผลลัพธ์ที่ควรเห็น: ถ้าเราล็อกอินเป็นไอดี 100 แต่เราเปลี่ยน URL เป็น /user/profile?id=101 ระบบจะแสดงข้อมูลของคนอื่นออกมาทันที ซึ่งเป็นการละเมิดสิทธิ์โดยตรง

วิธีแก้ไข Broken Access Control ให้ปลอดภัย

การแก้ไขคือเราต้องเช็กให้แน่ใจว่า userId ที่รับมา ตรงกับ session.userId (ไอดีของคนที่ล็อกอินอยู่ในขณะนั้น) หรือไม่ หากไม่ตรงกัน เราต้องปฏิเสธการเข้าถึงทันที นี่คือวิธีที่นักพัฒนาทุกคนต้องทำเป็นนิสัย

// โค้ดที่ถูก: ตรวจสอบสิทธิ์ก่อนแสดงข้อมูล
app.get('/user/profile', (req, res) => {
  const requestedId = req.query.id;
  const loggedInUser = req.session.user; // ข้อมูลคนที่ล็อกอิน

  if (loggedInUser.id !== requestedId) {
    return res.status(403).send('คุณไม่มีสิทธิ์เข้าถึงข้อมูลนี้');
  }
  
  const userData = db.getUserById(requestedId);
  res.send(userData);
});

อธิบายโค้ด:

  • req.session.user คือการดึงข้อมูลจากระบบล็อกอินที่ปลอดภัย ไม่ใช่จาก URL
  • เราใช้ if เพื่อเปรียบเทียบว่าคนเข้าใช้งานคือเจ้าของไอดีจริงหรือไม่
  • res.status(403) คือการแจ้งเตือนว่า "ห้ามเข้า" (Forbidden) หากสิทธิ์ไม่ถูกต้อง

ผลลัพธ์ที่ควรเห็น: เมื่อผู้ใช้งานพยายามเปลี่ยนเลขไอดีใน URL ระบบจะแสดงข้อความปฏิเสธและไม่ยอมปล่อยข้อมูลส่วนตัวของคนอื่นออกมา

A02: Security Misconfiguration คืออะไร

Security Misconfiguration คือความผิดพลาดจากการตั้งค่าระบบที่ไม่รัดกุม เช่น ทิ้งค่าเริ่มต้น (Default) ไว้ หรือลืมปิดฟีเจอร์บางอย่างที่ไม่ได้ใช้ ซึ่งเป็นช่องโหว่ที่แฮกเกอร์ใช้หาทางเข้าถึงระบบได้ง่ายที่สุดโดยไม่ต้องใช้เทคนิคซับซ้อนเลย

ตัวอย่างที่พบบ่อยคือ การเปิดแสดงข้อผิดพลาด (Error Message) แบบละเอียดเกินไปบนหน้าเว็บจริง เช่น เมื่อโค้ดบั๊ก แทนที่จะขึ้นว่า "ขออภัย เกิดข้อผิดพลาด" แต่ดันขึ้นรายละเอียดว่าไฟล์อยู่ที่ไหน ใช้ฐานข้อมูลอะไร หรือเวอร์ชันของโปรแกรมคืออะไร ข้อมูลเหล่านี้คือขุมทรัพย์ที่แฮกเกอร์ใช้หาทางเจาะระบบต่อ

นอกจากนี้ยังมีเรื่องของการเปิดพอร์ต (ช่องทางสื่อสารของคอมพิวเตอร์) ทิ้งไว้โดยไม่จำเป็น หรือการไม่ได้อัปเดตซอฟต์แวร์ให้เป็นเวอร์ชันล่าสุด การป้องกันที่ดีที่สุดคือการสร้าง Checklist (รายการตรวจสอบ) ก่อนนำโค้ดขึ้นเซิร์ฟเวอร์จริงทุกครั้ง เพื่อตรวจทานว่าเราไม่ได้เผลอเปิดประตูบ้านทิ้งไว้

ตัวอย่างการตั้งค่าที่ผิดพลาดในงานจริง

การเปิดโหมด Debug (โหมดแสดงรายละเอียดสำหรับนักพัฒนา) ทิ้งไว้บนเซิร์ฟเวอร์จริง เป็นความผิดพลาดระดับต้นๆ ที่มือใหม่มักเผลอทำ

// ตัวอย่างการตั้งค่าที่ผิด: แสดงรายละเอียดข้อผิดพลาด
app.use((err, req, res, next) => {
  // การส่ง stack trace (รายละเอียดลำดับการทำงานที่ผิดพลาด) ออกไปหน้าเว็บ
  res.status(500).send(err.stack); 
});

อธิบายโค้ด:

  • err.stack คือข้อมูลภายในที่บอกว่าโค้ดบรรทัดไหนพัง ไฟล์ชื่ออะไร อยู่ในโฟลเดอร์ไหน
  • การส่งข้อมูลนี้ให้ผู้ใช้งานเห็น ทำให้เขารู้โครงสร้างไฟล์ในเซิร์ฟเวอร์ของเราทันที
  • ในเซิร์ฟเวอร์จริง เราควรแสดงแค่ข้อความทั่วไป เพื่อไม่ให้ข้อมูลภายในรั่วไหล

ผลลัพธ์ที่ควรเห็น: หากโค้ดพัง ผู้ใช้งานจะเห็นรายละเอียดโครงสร้างโปรแกรมของเราทั้งหมดบนหน้าจอ ซึ่งเป็นข้อมูลที่แฮกเกอร์นำไปใช้ต่อยอดได้

สรุปบทเรียนและการนำไปใช้จริง

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

โปรแกรมเมอร์ทุกคนควรเริ่มทำ Checklist ส่วนตัวของตัวเอง เช่น ก่อนจะ Deploy (เอาโค้ดขึ้นเซิร์ฟเวอร์จริง) ให้เช็กเสมอว่า: 1. มีการตรวจสอบสิทธิ์ในทุก Endpoint (จุดรับส่งข้อมูล) หรือยัง 2. ปิดโหมดแสดงข้อผิดพลาดละเอียดๆ ไปหรือยัง 3. เปลี่ยนรหัสผ่านเริ่มต้นทั้งหมดแล้วใช่ไหม

การเป็นโปรแกรมเมอร์ที่เก่งไม่ได้วัดกันที่ว่าคุณเขียนโค้ดได้ซับซ้อนแค่ไหน แต่วัดกันที่ว่าคุณเขียนโค้ดที่ "ปลอดภัยและไว้ใจได้" แค่ไหน เริ่มต้นวันนี้ด้วยการใส่ใจเรื่องความปลอดภัยเล็กๆ น้อยๆ แล้วคุณจะกลายเป็นนักพัฒนาที่ทีมงานขาดไม่ได้แน่นอนครับ


ที่มา: Learning OWASP A01 and A02: Broken Access Control and Security Misconfiguration — DEV Community

แชร์บทความ

Facebook X LINE

บทความที่เกี่ยวข้อง

ทำไมการทำโปรเจกต์จริงถึงสำคัญกว่าการดูคลิปสอน สำหรับนักศึกษาและมือใหม่หัดเขียนโค้ด

ทำไมการทำโปรเจกต์จริงถึงสำคัญกว่าการดูคลิปสอน สำหรับนักศึกษาและมือใหม่หัดเขียนโค้ด

เลิกติดกับดักการดูคลิปสอน (Tutorial) แล้วมาเริ่มทำโปรเจกต์จริงกันดีกว่า เรียนรู้วิธีแก้บั๊ก การใช้ Git และการเลือกเครื่องมือให้เหมาะกับงาน เพื่อก้าวสู่การเป็นโปรแกรมเมอร์มืออาชีพ

ที่มา: DEV Community

45 minutes ago 9 นาที
2 views
เทคนิคเขียนแอป Flutter สำหรับ Meta Smart Glasses ให้ลื่นไหลและมีประสิทธิภาพ

เทคนิคเขียนแอป Flutter สำหรับ Meta Smart Glasses ให้ลื่นไหลและมีประสิทธิภาพ

เรียนรู้วิธีเขียนแอป Flutter เชื่อมต่อ Meta Smart Glasses ให้ทำงานเร็ว ไม่กระตุก ด้วยการวางสถาปัตยกรรมโค้ดและการจัดการข้อมูลแบบมือโปรที่มือใหม่ทำตามได้จริง

ที่มา: DEV Community

8 hours ago 10 นาที
5 views
เปรียบเทียบ WebSocket, SSE และ Polling เลือกวิธีทำระบบ Real-Time ให้เหมาะกับงาน

เปรียบเทียบ WebSocket, SSE และ Polling เลือกวิธีทำระบบ Real-Time ให้เหมาะกับงาน

อยากทำระบบ Real-Time แต่ไม่รู้จะเลือกใช้ Polling, SSE หรือ WebSocket ดี? มาดูวิธีเลือกใช้ให้เหมาะกับงาน เพื่อให้แอปของคุณทำงานลื่นไหลและประหยัดทรัพยากรเซิร์ฟเวอร์

ที่มา: DEV Community

12 hours ago 10 นาที
5 views