จอคอมพิวเตอร์แก้วใสแสดงหน้าต่างเบราว์เซอร์ว่าง กับเซิร์ฟเวอร์แก้วใส มีก้อนข้อมูลเรืองแสงสีฟ้าและทองวิ่งไปมาระหว่างกัน

Cyber 101 · บทที่ 2

เว็บทำงานอย่างไร มองจากสองฝั่ง

เว็บคือบทสนทนาระหว่างไคลเอนต์กับเซิร์ฟเวอร์

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

ไคลเอนต์ (client)

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

เซิร์ฟเวอร์ (server)

คือเครื่องปลายทางที่เก็บข้อมูลและ logic สำคัญ หน้าที่คือรับคำขอ ตรวจสอบ แล้วส่งคำตอบ (response) กลับมา กฎเหล็กของฝั่งป้องกันคือ การตัดสินใจเรื่องสิทธิและความถูกต้องต้องเกิดที่ฝั่งนี้เท่านั้น

หนึ่งคำขอ หนึ่งคำตอบ (request / response)

HTTP คือภาษาที่สองฝั่งใช้คุยกัน แต่ละคำขอประกอบด้วยบรรทัดแรกที่บอก method และเส้นทาง ตามด้วย headers ที่เป็นข้อมูลกำกับ และบางครั้งมี body ที่เป็นข้อมูลจริง คำตอบก็มีโครงคล้ายกันแต่ขึ้นต้นด้วยรหัสสถานะ ลองดูตัวอย่างคำขอและคำตอบแบบง่าย ๆ เพื่อจับโครงสร้าง

ตัวอย่างคำขอที่เบราว์เซอร์ส่งไปขอหน้าเข้าสู่ระบบ

GET /login HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0
Accept: text/html

ตัวอย่างคำตอบจากเซิร์ฟเวอร์ สังเกตบรรทัดสถานะและ headers

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax

จะเห็นว่าไม่มีอะไรลึกลับ ทุกอย่างเป็นข้อความที่อ่านได้ ความเข้าใจตรงนี้คือรากฐานของทุกบทถัดไป เพราะช่องโหว่เว็บส่วนใหญ่เกิดจากการที่ข้อความเหล่านี้ถูกไว้ใจหรือถูกจัดการอย่างไม่รอบคอบ

GET

ขอข้อมูลมาอ่าน ไม่ควรใช้เปลี่ยนแปลงข้อมูล และไม่ควรใส่ข้อมูลลับไว้ใน URL เพราะถูกบันทึกใน log และประวัติได้ง่าย

POST

ส่งข้อมูลไปสร้างหรือประมวลผล เช่น ล็อกอินหรือส่งฟอร์ม ข้อมูลอยู่ใน body ไม่โผล่ใน URL

PUT / PATCH

ใช้แก้ไขข้อมูลที่มีอยู่ ต้องตรวจสิทธิที่เซิร์ฟเวอร์ทุกครั้งก่อนยอมให้แก้

DELETE

ใช้ลบข้อมูล เป็น method ที่ต้องระวังเรื่องสิทธิเป็นพิเศษ

2xx สำเร็จ

เช่น 200 OK คำขอสำเร็จและได้คำตอบตามต้องการ

3xx เปลี่ยนเส้นทาง

เช่น 301/302 บอกให้เบราว์เซอร์ไปที่อยู่ใหม่

4xx ผิดฝั่งผู้ขอ

เช่น 401 ยังไม่ยืนยันตัวตน, 403 ไม่มีสิทธิ, 404 ไม่พบ

5xx ผิดฝั่งเซิร์ฟเวอร์

เช่น 500 เซิร์ฟเวอร์มีข้อผิดพลาดภายใน อย่าเผยรายละเอียด error ให้ผู้ใช้เห็น

🧪 ลองในแล็บของคุณ

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

ดูบรรทัดสถานะและ headers ของคำตอบด้วย curl

curl -i https://example.com

ลองเปลี่ยน URL เป็นเว็บของตัวเองหรือแอปที่รันบน localhost ของเรา แล้วสังเกตว่ารหัสสถานะและ Content-Type ตรงกับที่คาดไว้ไหม นี่คือการฝึกอ่านบทสนทนา HTTP ด้วยตาเปล่า

คุกกี้ เซสชัน และเฮดเดอร์ที่เกี่ยวกับความปลอดภัย

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

คุกกี้และเซสชันคืออะไร

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

แนวคิดการโจมตี: การขโมยเซสชัน (session hijacking)

ถ้าผู้โจมตีได้ค่า session id ของเหยื่อไป เขาก็สวมรอยเป็นเหยื่อได้ทันทีโดยไม่ต้องรู้รหัสผ่าน วิธีที่มักถูกพูดถึงคือดักฟังทราฟฟิกที่ไม่ได้เข้ารหัส หรือใช้ช่องโหว่ XSS ดึงคุกกี้ออกไป เราเรียนแนวคิดนี้ "เพื่อรู้ว่าจะปกป้องบัตรผ่านอย่างไร" ไม่ใช่เพื่อนำไปทำกับใคร รายละเอียดของ XSS จะอยู่ในบทถัดไป ในบทนี้ขอโฟกัสที่การป้องกันคุกกี้เอง

🛡️ วิธีป้องกัน

  • HttpOnly ทำให้ JavaScript อ่านคุกกี้ไม่ได้ ลดผลกระทบจาก XSS ที่พยายามขโมยคุกกี้
  • Secure ส่งคุกกี้เฉพาะบน HTTPS เท่านั้น กันการดักฟังบนช่องทางที่ไม่เข้ารหัส
  • SameSite=Lax หรือ Strict ลดการแนบคุกกี้ข้ามเว็บ ช่วยกัน CSRF
  • ออก session id ใหม่หลังล็อกอิน (session regeneration) และตั้งอายุให้สั้น พร้อมมีปุ่มออกจากระบบที่ยกเลิกเซสชันจริงที่ฝั่งเซิร์ฟเวอร์
  • บังคับ HTTPS ทั้งเว็บ เพื่อไม่ให้บัตรผ่านวิ่งผ่านช่องทางที่อ่านได้

คุกกี้เซสชันที่ตั้งค่าธงป้องกันครบ (ฝั่งเซิร์ฟเวอร์เป็นคนกำหนด)

Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Max-Age=1800

เฮดเดอร์ความปลอดภัยที่ควรรู้จัก

เซิร์ฟเวอร์สามารถส่ง response headers บางตัวเพื่อสั่งให้เบราว์เซอร์ช่วยป้องกันตัวเอง นี่คือการป้องกันแบบไม่ต้องแก้โค้ดหน้าเว็บมาก ควรตั้งเป็นค่ามาตรฐานของเว็บทุกตัวที่เราดูแล

เฮดเดอร์ทำหน้าที่อะไร
Strict-Transport-Securityบังคับให้เบราว์เซอร์ใช้ HTTPS เสมอ
Content-Security-Policyจำกัดว่าสคริปต์และทรัพยากรโหลดจากที่ใดได้บ้าง ช่วยลดผล XSS
X-Content-Type-Options: nosniffกันเบราว์เซอร์เดาชนิดไฟล์ผิด
X-Frame-Options / frame-ancestorsกันเว็บเราถูกฝังใน iframe เพื่อหลอกคลิก (clickjacking)

⚠️ จริยธรรมและกฎหมาย

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

🧪 ลองในแล็บของคุณ

ล็อกอินเข้าเว็บของตัวเองหรือแอปบน localhost ที่เราสร้างขึ้น แล้วเปิด DevTools ไปที่แท็บ Application (หรือ Storage) เพื่อดูคุกกี้ของเซสชันเรา สังเกตว่ามีธง HttpOnly, Secure และ SameSite ครบหรือไม่ ถ้ายังไม่ครบ ให้ลองเพิ่มในโค้ดฝั่งเซิร์ฟเวอร์ของเราแล้วรีเฟรชดูผล นี่คือการฝึกมองเว็บจากฝั่งเจ้าของระบบ

อ่านการทำงานจริงด้วย Browser DevTools

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

แท็บ Network

แสดงคำขอทุกอันที่หน้านี้ยิงออกไป พร้อมสถานะ เวลา ขนาด และรายละเอียด headers/response คลิกดูทีละอันได้

แท็บ Application

ดูคุกกี้ local storage และ session storage ที่เว็บเก็บไว้ในเบราว์เซอร์ของเรา

แท็บ Console

เห็น error และข้อความ log ของหน้าเว็บ ช่วยเข้าใจว่าโค้ดฝั่งไคลเอนต์ทำงานอย่างไร

อ่านคำขอทีละอันในแท็บ Network

เมื่อเปิดแท็บ Network แล้วรีเฟรชหน้า เราจะเห็นรายการคำขอไหลเข้ามา ลองคลิกที่คำขอหนึ่งอัน แล้วดูส่วน Headers เพื่ออ่าน method, สถานะ, request headers และ response headers ส่วน Payload หรือ Request บอกข้อมูลที่ส่งไป และส่วน Response บอกสิ่งที่ได้กลับมา การฝึกอ่านตรงนี้ทำให้เราเข้าใจว่าเว็บที่เราดูแล ส่งข้อมูลอะไรออกไปบ้าง และมีข้อมูลลับหลุดออกไปโดยไม่ตั้งใจหรือไม่

🧪 ลองในแล็บของคุณ

เปิดเว็บของตัวเองหรือแอปบน localhost ของเรา กด F12 ไปที่แท็บ Network แล้วรีเฟรช สังเกตว่าไฟล์ใหญ่ที่สุดคืออะไร คำขอไหนช้าที่สุด และคำขอล็อกอินส่งอะไรไปบ้าง จากนั้นไปแท็บ Application ดูว่าเว็บเราเก็บข้อมูลอะไรไว้ในเบราว์เซอร์ ลองตั้งคำถามว่า "ถ้าเป็นเจ้าของระบบ ข้อมูลชิ้นนี้ควรอยู่ตรงนี้ไหม"

⚠️ จริยธรรมและกฎหมาย

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

สร้างสนามฝึกของตัวเอง

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

เขียนแอปเล็ก ๆ ของตัวเองเป็นสนามฝึก

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

OWASP Juice Shop

เว็บฝึกยอดนิยมที่จงใจมีช่องโหว่ครบทุกหมวด ติดตั้งบนเครื่องเราได้ง่าย เหมาะกับผู้เริ่มต้น owasp.org/www-project-juice-shop

DVWA

Damn Vulnerable Web Application ปรับระดับความยากได้ เหมาะฝึกทีละหัวข้อ github.com/digininja/DVWA

picoCTF

สนาม CTF ออนไลน์ที่ถูกกฎหมาย เหมาะฝึกโจทย์เป็นด่าน ๆ picoctf.org

PortSwigger Academy

คอร์สความปลอดภัยเว็บฟรีพร้อมแล็บในเบราว์เซอร์ที่ทางเว็บจัดให้ portswigger.net/web-security

🧪 ลองในแล็บของคุณ

ติดตั้ง OWASP Juice Shop ไว้ในเครื่องตัวเอง วิธีที่ง่ายที่สุดคือใช้ Docker และผูกพอร์ตไว้กับ localhost เท่านั้น เพื่อไม่ให้ใครจากภายนอกเข้าถึงได้

รัน Juice Shop โดยเปิดพอร์ตเฉพาะที่เครื่องเรา

docker run -d -p 127.0.0.1:3000:3000 bkimminich/juice-shop

จากนั้นเปิด http://localhost:3000 ในเบราว์เซอร์ แล้วลองใช้ DevTools แท็บ Network สำรวจว่าเว็บนี้คุยกับเซิร์ฟเวอร์อย่างไร ยังไม่ต้องพยายามเจาะอะไร แค่ฝึก "อ่าน" การทำงานของมันก่อน ส่วนการฝึกหาช่องโหว่จะค่อย ๆ ทำในบทถัด ๆ ไป โดยทั้งหมดทำบนสำเนาที่รันในเครื่องเราเอง

🛡️ วิธีป้องกัน

สนามฝึกที่มีช่องโหว่โดยตั้งใจ ต้องถูกกักให้อยู่ในบ้านของเราเสมอ หลักปฏิบัติคือ

  • ผูกพอร์ตไว้กับ 127.0.0.1 อย่าเปิดออกอินเทอร์เน็ต และอย่าวางไว้บนเซิร์ฟเวอร์สาธารณะ
  • ถ้าใช้ VM ให้ตั้งเครือข่ายแบบ host-only แยกออกจากเครือข่ายบ้าน และใช้ snapshot เพื่อย้อนคืนสถานะได้
  • อย่าใส่ข้อมูลจริงของตัวเองหรือคนอื่นลงในเว็บฝึก ใช้ข้อมูลสมมติเท่านั้น
  • ปิดหรือลบสนามฝึกเมื่อเลิกใช้ เพราะมันคือระบบที่ตั้งใจให้อ่อนแอ

⚠️ จริยธรรมและกฎหมาย

เว็บฝึกเหล่านี้ถูกกฎหมายก็ต่อเมื่อเรารันสำเนาของมันในเครื่องของเราเอง หรือใช้สนามฝึกออนไลน์ตามกติกาที่ผู้ให้บริการอนุญาตไว้ การนำเทคนิคหรือเครื่องมือไปทดสอบกับเว็บของบุคคลหรือองค์กรอื่นที่ไม่ได้ยินยอมเป็นลายลักษณ์อักษร ถือเป็นการเข้าถึงระบบโดยมิชอบตาม พ.ร.บ.คอมพิวเตอร์ พ.ศ. 2560 (เป็นความรู้ทั่วไป ไม่ใช่คำแนะนำทางกฎหมาย) กฎทองของคอร์สนี้คือ ฝึกเฉพาะระบบที่เป็นของเรา หรือที่ได้รับอนุญาตและมีขอบเขตชัดเจนเท่านั้น

ทบทวนท้ายบท

ลองตอบคำถามเหล่านี้ในใจก่อนกดดูเฉลย เพื่อเช็คว่าเราเข้าใจภาพรวมของบทนี้ครบแล้วหรือยัง

❓ คำถาม: ทำไมการตรวจสอบสิทธิและความถูกต้องของข้อมูลจึงต้องทำที่ฝั่งเซิร์ฟเวอร์เสมอ
เฉลย: เพราะฝั่งไคลเอนต์ (เบราว์เซอร์) ผู้ใช้มองเห็นและแก้ไขได้ทั้งหมด ไม่ว่าจะเป็น JavaScript, ฟอร์ม หรือคำขอ HTTP จึงไว้ใจไม่ได้ว่าข้อมูลที่ส่งมาจะถูกต้องหรือปลอดภัย การตัดสินใจเรื่องสิทธิและการตรวจความถูกต้องจึงต้องทำที่เซิร์ฟเวอร์ซึ่งเราควบคุมได้จริง
❓ คำถาม: ธง HttpOnly, Secure และ SameSite บนคุกกี้เซสชัน ช่วยป้องกันอะไรได้บ้าง
เฉลย: HttpOnly ทำให้ JavaScript อ่านคุกกี้ไม่ได้ ลดผลกระทบจาก XSS ที่พยายามขโมยเซสชัน; Secure ทำให้คุกกี้ถูกส่งเฉพาะบน HTTPS จึงกันการดักฟังบนช่องทางที่ไม่เข้ารหัส; SameSite ลดการแนบคุกกี้ข้ามเว็บ ช่วยลดความเสี่ยง CSRF ทั้งสามอย่างช่วยกันปกป้อง "บัตรผ่าน" ของผู้ใช้
❓ คำถาม: อยากฝึกหาช่องโหว่เว็บให้ถูกกฎหมาย ควรเริ่มที่ไหน และมีข้อควรระวังอะไร
เฉลย: เริ่มจากรันเว็บฝึกที่จงใจมีช่องโหว่บนเครื่องตัวเอง เช่น OWASP Juice Shop หรือ DVWA หรือใช้สนามฝึกออนไลน์ที่อนุญาตอย่าง picoCTF และ PortSwigger Academy ข้อควรระวังคือ กักสนามฝึกไว้ที่ localhost หรือ VM แบบ host-only อย่าเปิดออกอินเทอร์เน็ต ใช้ข้อมูลสมมติเท่านั้น และห้ามนำเทคนิคไปทดสอบกับระบบของผู้อื่นที่ไม่ได้อนุญาตเป็นลายลักษณ์อักษรเด็ดขาด
❓ คำถาม: DevTools แท็บ Network กับแท็บ Application ต่างกันอย่างไร และใช้ตอนไหน
เฉลย: แท็บ Network ใช้ดูคำขอและคำตอบ HTTP ทุกอันที่หน้าเว็บส่งจริง พร้อม method สถานะ และ headers เหมาะกับการเข้าใจการสื่อสารระหว่างไคลเอนต์กับเซิร์ฟเวอร์; ส่วนแท็บ Application ใช้ดูสิ่งที่เว็บเก็บไว้ในเบราว์เซอร์ เช่น คุกกี้ local storage และ session storage เหมาะกับการตรวจว่าข้อมูลอะไรถูกเก็บไว้และตั้งค่าธงความปลอดภัยครบหรือไม่